Import Cobalt 22.master.0.304062
diff --git a/src/base/files/file_path.cc b/src/base/files/file_path.cc
index 043d144..4ce94c9 100644
--- a/src/base/files/file_path.cc
+++ b/src/base/files/file_path.cc
@@ -5,11 +5,10 @@
 #include "base/files/file_path.h"
 
 #include <string.h>
+
 #include <algorithm>
-
-#include "starboard/types.h"
-
-#include "starboard/common/string.h"
+#include <set>
+#include <string>
 
 #include "base/logging.h"
 #include "base/macros.h"
@@ -19,6 +18,8 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "starboard/common/string.h"
+#include "starboard/types.h"
 
 #if defined(OS_MACOSX)
 #include "base/mac/scoped_cftyperef.h"
@@ -57,7 +58,28 @@
        (path[0] >= L'a' && path[0] <= L'z'))) {
     return 1;
   }
-#endif  // FILE_PATH_USES_DRIVE_LETTERS
+#elif defined(FILE_PATH_USES_MOUNT_POINT_NAME)
+  StringType::size_type delimiter_position = std::string(path).find(":");
+
+  auto has_disabled_symbols = [](std::string test_string) {
+    std::set<char> disabled_set = {'*', ':', '<', '>', '?', '|'};
+    std::set<char> tmp(test_string.begin(), test_string.end());
+    std::set<char> intersect;
+    std::set_intersection(disabled_set.begin(), disabled_set.end(), tmp.begin(),
+                          tmp.end(),
+                          std::inserter(intersect, intersect.begin()));
+    return !intersect.empty();
+  };
+  std::string mount_point = std::string(path).substr(0, delimiter_position);
+  std::string file_name = std::string(path).substr(delimiter_position + 1);
+  if (has_disabled_symbols(mount_point) || has_disabled_symbols(file_name)) {
+    return StringType::npos;
+  }
+
+  if (mount_point.size() >= 2 && delimiter_position != std::string::npos) {
+    return delimiter_position;
+  }
+#endif
   return StringType::npos;
 }
 
@@ -81,7 +103,8 @@
 #endif  // defined(FILE_PATH_USES_DRIVE_LETTERS)
 
 bool IsPathAbsolute(StringPieceType path) {
-#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+#if defined(FILE_PATH_USES_DRIVE_LETTERS) || \
+    defined(FILE_PATH_USES_MOUNT_POINT_NAME)
   StringType::size_type letter = FindDriveLetter(path);
   if (letter != StringType::npos) {
     // Look for a separator right after the drive specification.
@@ -91,10 +114,10 @@
   // Look for a pair of leading separators.
   return path.length() > 1 &&
       FilePath::IsSeparator(path[0]) && FilePath::IsSeparator(path[1]);
-#else  // FILE_PATH_USES_DRIVE_LETTERS
+#else  // FILE_PATH_USES_DRIVE_LETTERS || FILE_PATH_USES_MOUNT_POINT_NAME
   // Look for a separator in the first position.
   return path.length() > 0 && FilePath::IsSeparator(path[0]);
-#endif  // FILE_PATH_USES_DRIVE_LETTERS
+#endif  // FILE_PATH_USES_DRIVE_LETTERS || FILE_PATH_USES_MOUNT_POINT_NAME
 }
 
 bool AreAllSeparators(const StringType& input) {
diff --git a/src/base/files/file_path_unittest.cc b/src/base/files/file_path_unittest.cc
index 593b1a0..f7c698a 100644
--- a/src/base/files/file_path_unittest.cc
+++ b/src/base/files/file_path_unittest.cc
@@ -415,12 +415,31 @@
     { FPL("c:/.."),  true },
     { FPL("C:/a"),   true },
     { FPL("d:/a"),   true },
-#else  // FILE_PATH_USES_DRIVE_LETTERS
-    { FPL("/"),      true },
-    { FPL("/a"),     true },
-    { FPL("/."),     true },
-    { FPL("/.."),    true },
-    { FPL("c:/"),    false },
+#elif defined(FILE_PATH_USES_MOUNT_POINT_NAME)
+    { FPL("/"),         false },
+    { FPL("/a"),        false },
+    { FPL("/."),        false },
+    { FPL("/.."),       false },
+    { FPL("ab:/."),     true  },
+    { FPL("ab:/"),      true  },
+    { FPL("ab:"),       false },
+    { FPL("b:"),        false },
+    { FPL("b:/"),       false },
+    { FPL("cache:/"),   true },
+    { FPL("rom:/"),     true },
+    { FPL("cache:/."),  true },
+    { FPL("rom:/."),    true },
+    { FPL("cache:/a"),  true },
+    { FPL("rom:/a"),    true },
+    { FPL("cache:/.."), true },
+    { FPL("rom:/.."),   true },
+#else  // !defined(FILE_PATH_USES_DRIVE_LETTERS) && \
+          !defined(FILE_PATH_USES_MOUNT_POINT_NAME)
+    { FPL("/"),   true },
+    { FPL("/a"),  true },
+    { FPL("/."),  true },
+    { FPL("/.."), true },
+    { FPL("c:/"), false },
 #endif  // FILE_PATH_USES_DRIVE_LETTERS
 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
     { FPL("a\\b"),   false },
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 0c55a1f..97ccdad 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-303689
\ No newline at end of file
+304062
\ No newline at end of file
diff --git a/src/cobalt/build/save_build_id.py b/src/cobalt/build/save_build_id.py
index 014e80d..fc81ab9 100755
--- a/src/cobalt/build/save_build_id.py
+++ b/src/cobalt/build/save_build_id.py
@@ -63,7 +63,12 @@
     return 0
 
   if not options.build_id:
-    options.build_id = gyp_utils.GetBuildNumber()
+    build_id_server_url = os.environ.get('BUILD_ID_SERVER_URL')
+    if build_id_server_url:
+      options.build_id = gyp_utils.GetBuildNumber(
+          version_server=build_id_server_url)
+    else:
+      options.build_id = gyp_utils.GetBuildNumber()
 
   if not options.build_id:
     logging.error('Unable to retrieve build id.')
diff --git a/src/cobalt/content/fonts/BUILD.gn b/src/cobalt/content/fonts/BUILD.gn
index 87b11ff..8b99258 100644
--- a/src/cobalt/content/fonts/BUILD.gn
+++ b/src/cobalt/content/fonts/BUILD.gn
@@ -30,7 +30,7 @@
              "-i",
              rebase_path(font_xml, root_build_dir),
              "-o",
-             outputs[0],
+             rebase_path(outputs[0], root_out_dir),
            ] + package_categories
   }
 
diff --git a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp b/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
deleted file mode 100644
index 39ad8b2..0000000
--- a/src/cobalt/debug/remote/devtools/copy_devtools_modules.rsp
+++ /dev/null
@@ -1,476 +0,0 @@
-front_end/network/network.js
-front_end/network/SignedExchangeInfoView.js
-front_end/network/ResourceWebSocketFrameView.js
-front_end/network/RequestTimingView.js
-front_end/network/RequestResponseView.js
-front_end/network/RequestPreviewView.js
-front_end/network/RequestInitiatorView.js
-front_end/network/RequestHeadersView.js
-front_end/network/RequestHTMLView.js
-front_end/network/RequestCookiesView.js
-front_end/network/NetworkWaterfallColumn.js
-front_end/network/NetworkTimeCalculator.js
-front_end/network/NetworkSearchScope.js
-front_end/network/NetworkPanel.js
-front_end/network/NetworkOverview.js
-front_end/network/NetworkManageCustomHeadersView.js
-front_end/network/NetworkLogViewColumns.js
-front_end/network/NetworkLogView.js
-front_end/network/NetworkItemView.js
-front_end/network/NetworkFrameGrouper.js
-front_end/network/NetworkDataGridNode.js
-front_end/network/NetworkConfigView.js
-front_end/network/HARWriter.js
-front_end/network/EventSourceMessagesView.js
-front_end/network/BlockedURLsPane.js
-front_end/network/BinaryResourceView.js
-front_end/test_runner/test_runner.js
-front_end/test_runner/TestRunner.js
-front_end/emulation/emulation.js
-front_end/emulation/SensorsView.js
-front_end/emulation/MediaQueryInspector.js
-front_end/emulation/InspectedPagePlaceholder.js
-front_end/emulation/GeolocationsSettingsTab.js
-front_end/emulation/EmulatedDevices.js
-front_end/emulation/DevicesSettingsTab.js
-front_end/emulation/DeviceModeWrapper.js
-front_end/emulation/DeviceModeView.js
-front_end/emulation/DeviceModeToolbar.js
-front_end/emulation/DeviceModeModel.js
-front_end/emulation/AdvancedApp.js
-front_end/inspector_main/inspector_main.js
-front_end/inspector_main/RenderingOptions.js
-front_end/inspector_main/InspectorMain.js
-front_end/js_main/js_main.js
-front_end/js_main/JsMain.js
-front_end/search/search.js
-front_end/search/SearchView.js
-front_end/search/SearchResultsPane.js
-front_end/search/SearchConfig.js
-front_end/screencast/screencast.js
-front_end/screencast/ScreencastView.js
-front_end/screencast/ScreencastApp.js
-front_end/screencast/InputModel.js
-front_end/performance_monitor/performance_monitor.js
-front_end/performance_monitor/PerformanceMonitor.js
-front_end/main/main.js
-front_end/main/SimpleApp.js
-front_end/main/MainImpl.js
-front_end/main/ExecutionContextSelector.js
-front_end/snippets/snippets.js
-front_end/snippets/SnippetsQuickOpen.js
-front_end/snippets/ScriptSnippetFileSystem.js
-front_end/settings/settings.js
-front_end/settings/SettingsScreen.js
-front_end/settings/FrameworkBlackboxSettingsTab.js
-front_end/security/security.js
-front_end/security/SecurityPanel.js
-front_end/security/SecurityModel.js
-front_end/javascript_metadata/javascript_metadata.js
-front_end/javascript_metadata/NativeFunctions.js
-front_end/javascript_metadata/JavaScriptMetadata.js
-front_end/har_importer/har_importer.js
-front_end/har_importer/HARImporter.js
-front_end/har_importer/HARFormat.js
-front_end/browser_debugger/browser_debugger.js
-front_end/browser_debugger/XHRBreakpointsSidebarPane.js
-front_end/browser_debugger/ObjectEventListenersSidebarPane.js
-front_end/browser_debugger/EventListenerBreakpointsSidebarPane.js
-front_end/browser_debugger/DOMBreakpointsSidebarPane.js
-front_end/layer_viewer/layer_viewer.js
-front_end/layer_viewer/TransformController.js
-front_end/layer_viewer/PaintProfilerView.js
-front_end/layer_viewer/Layers3DView.js
-front_end/layer_viewer/LayerViewHost.js
-front_end/layer_viewer/LayerTreeOutline.js
-front_end/layer_viewer/LayerDetailsView.js
-front_end/cm_web_modes/cm_web_modes.js
-front_end/cm_web_modes/cm_web_modes_cm.js
-front_end/cm_web_modes/cm_web_modes_headless.js
-front_end/cm_web_modes/css.js
-front_end/cm_web_modes/javascript.js
-front_end/cm_web_modes/xml.js
-front_end/cm_web_modes/htmlmixed.js
-front_end/cm_web_modes/htmlembedded.js
-front_end/text_editor/text_editor.js
-front_end/text_editor/TextEditorAutocompleteController.js
-front_end/text_editor/CodeMirrorUtils.js
-front_end/text_editor/CodeMirrorTextEditor.js
-front_end/quick_open/quick_open.js
-front_end/quick_open/QuickOpen.js
-front_end/quick_open/HelpQuickOpen.js
-front_end/quick_open/FilteredListWidget.js
-front_end/quick_open/CommandMenu.js
-front_end/elements/elements.js
-front_end/elements/elements-legacy.js
-front_end/elements/StylesSidebarPane.js
-front_end/elements/StylePropertyTreeElement.js
-front_end/elements/StylePropertyHighlighter.js
-front_end/elements/PropertiesWidget.js
-front_end/elements/PlatformFontsWidget.js
-front_end/elements/NodeStackTraceWidget.js
-front_end/elements/MetricsSidebarPane.js
-front_end/elements/MarkerDecorator.js
-front_end/elements/InspectElementModeController.js
-front_end/elements/EventListenersWidget.js
-front_end/elements/ElementsTreeOutline.js
-front_end/elements/ElementsTreeElement.js
-front_end/elements/ElementsTreeElementHighlighter.js
-front_end/elements/ElementStatePaneWidget.js
-front_end/elements/ElementsSidebarPane.js
-front_end/elements/ElementsPanel.js
-front_end/elements/ElementsBreadcrumbs.js
-front_end/elements/DOMPath.js
-front_end/elements/DOMLinkifier.js
-front_end/elements/ComputedStyleWidget.js
-front_end/elements/ComputedStyleModel.js
-front_end/elements/ColorSwatchPopoverIcon.js
-front_end/elements/ClassesPaneWidget.js
-front_end/timeline_model/timeline_model.js
-front_end/timeline_model/TracingLayerTree.js
-front_end/timeline_model/TimelineProfileTree.js
-front_end/timeline_model/TimelineModel.js
-front_end/timeline_model/TimelineModelFilter.js
-front_end/timeline_model/TimelineJSProfile.js
-front_end/timeline_model/TimelineIRModel.js
-front_end/timeline_model/TimelineFrameModel.js
-front_end/help/help.js
-front_end/help/ReleaseNoteView.js
-front_end/help/ReleaseNoteText.js
-front_end/help/HelpImpl.js
-front_end/workspace_diff/workspace_diff.js
-front_end/workspace_diff/WorkspaceDiff.js
-front_end/mobile_throttling/mobile_throttling.js
-front_end/mobile_throttling/ThrottlingSettingsTab.js
-front_end/mobile_throttling/ThrottlingPresets.js
-front_end/mobile_throttling/ThrottlingManager.js
-front_end/mobile_throttling/NetworkThrottlingSelector.js
-front_end/mobile_throttling/NetworkPanelIndicator.js
-front_end/mobile_throttling/MobileThrottlingSelector.js
-front_end/event_listeners/event_listeners.js
-front_end/event_listeners/EventListenersView.js
-front_end/event_listeners/EventListenersUtils.js
-front_end/object_ui/object_ui.js
-front_end/object_ui/RemoteObjectPreviewFormatter.js
-front_end/object_ui/ObjectPropertiesSection.js
-front_end/object_ui/ObjectPopoverHelper.js
-front_end/object_ui/JavaScriptREPL.js
-front_end/object_ui/JavaScriptAutocomplete.js
-front_end/object_ui/CustomPreviewComponent.js
-front_end/cookie_table/cookie_table.js
-front_end/cookie_table/CookiesTable.js
-front_end/cm_modes/cm_modes.js
-front_end/cm_modes/DefaultCodeMirrorMimeMode.js
-front_end/cm_modes/clike.js
-front_end/cm_modes/coffeescript.js
-front_end/cm_modes/php.js
-front_end/cm_modes/python.js
-front_end/cm_modes/shell.js
-front_end/cm_modes/livescript.js
-front_end/cm_modes/markdown.js
-front_end/cm_modes/clojure.js
-front_end/cm_modes/jsx.js
-front_end/css_overview/css_overview.js
-front_end/css_overview/CSSOverviewUnusedDeclarations.js
-front_end/css_overview/CSSOverviewStartView.js
-front_end/css_overview/CSSOverviewSidebarPanel.js
-front_end/css_overview/CSSOverviewProcessingView.js
-front_end/css_overview/CSSOverviewPanel.js
-front_end/css_overview/CSSOverviewModel.js
-front_end/css_overview/CSSOverviewController.js
-front_end/css_overview/CSSOverviewCompletedView.js
-front_end/console/console.js
-front_end/console/ConsoleContextSelector.js
-front_end/console/ConsoleFilter.js
-front_end/console/ConsoleSidebar.js
-front_end/console/ConsolePanel.js
-front_end/console/ConsolePinPane.js
-front_end/console/ConsolePrompt.js
-front_end/console/ConsoleView.js
-front_end/console/ConsoleViewMessage.js
-front_end/console/ConsoleViewport.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/XMLView.js
-front_end/source_frame/SourcesTextEditor.js
-front_end/source_frame/SourceFrame.js
-front_end/source_frame/source_frame.js
-front_end/source_frame/SourceCodeDiff.js
-front_end/source_frame/ResourceSourceFrame.js
-front_end/source_frame/PreviewFactory.js
-front_end/source_frame/JSONView.js
-front_end/source_frame/ImageView.js
-front_end/source_frame/FontView.js
-front_end/source_frame/BinaryResourceViewFactory.js
-front_end/inline_editor/inline_editor.js
-front_end/inline_editor/SwatchPopoverHelper.js
-front_end/inline_editor/CSSShadowModel.js
-front_end/inline_editor/CSSShadowEditor.js
-front_end/inline_editor/ColorSwatch.js
-front_end/inline_editor/BezierUI.js
-front_end/inline_editor/BezierEditor.js
-front_end/diff/diff.js
-front_end/diff/diff_match_patch.js
-front_end/diff/DiffWrapper.js
-front_end/formatter/formatter.js
-front_end/formatter/ScriptFormatter.js
-front_end/formatter/FormatterWorkerPool.js
-front_end/color_picker/color_picker.js
-front_end/color_picker/Spectrum.js
-front_end/color_picker/ContrastOverlay.js
-front_end/color_picker/ContrastInfo.js
-front_end/color_picker/ContrastDetails.js
-front_end/cm/cm.js
-front_end/cm/active-line.js
-front_end/cm/brace-fold.js
-front_end/cm/closebrackets.js
-front_end/cm/codemirror.js
-front_end/cm/comment.js
-front_end/cm/foldcode.js
-front_end/cm/foldgutter.js
-front_end/cm/mark-selection.js
-front_end/cm/matchbrackets.js
-front_end/cm/multiplex.js
-front_end/cm/overlay.js
-front_end/formatter_worker.unbundled.js
-front_end/heap_snapshot_worker.unbundled.js
-front_end/heap_snapshot_model/heap_snapshot_model.js
-front_end/heap_snapshot_model/HeapSnapshotModel.js
-front_end/heap_snapshot_worker/heap_snapshot_worker.js
-front_end/heap_snapshot_worker/AllocationProfile.js
-front_end/heap_snapshot_worker/HeapSnapshot.js
-front_end/heap_snapshot_worker/HeapSnapshotLoader.js
-front_end/heap_snapshot_worker/HeapSnapshotWorker.js
-front_end/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
-front_end/text_utils/text_utils.js
-front_end/text_utils/TextUtils.js
-front_end/text_utils/TextRange.js
-front_end/text_utils/Text.js
-front_end/formatter_worker/formatter_worker.js
-front_end/formatter_worker/RelaxedJSONParser.js
-front_end/formatter_worker/JavaScriptOutline.js
-front_end/formatter_worker/JavaScriptFormatter.js
-front_end/formatter_worker/IdentityFormatter.js
-front_end/formatter_worker/HTMLFormatter.js
-front_end/formatter_worker/FormatterWorker.js
-front_end/formatter_worker/FormattedContentBuilder.js
-front_end/formatter_worker/ESTreeWalker.js
-front_end/formatter_worker/CSSRuleParser.js
-front_end/formatter_worker/CSSFormatter.js
-front_end/formatter_worker/AcornTokenizer.js
-front_end/cm_headless/cm_headless.js
-front_end/cm_headless/headlesscodemirror.js
-front_end/data_grid/data_grid.js
-front_end/data_grid/ViewportDataGrid.js
-front_end/data_grid/SortableDataGrid.js
-front_end/data_grid/ShowMoreDataGridNode.js
-front_end/data_grid/DataGrid.js
-front_end/protocol_monitor/protocol_monitor.js
-front_end/protocol_monitor/ProtocolMonitor.js
-front_end/console_counters/console_counters.js
-front_end/console_counters/WarningErrorCounter.js
-front_end/extensions/extensions.js
-front_end/extensions/ExtensionAPI.js
-front_end/extensions/ExtensionPanel.js
-front_end/extensions/ExtensionServer.js
-front_end/extensions/ExtensionTraceProvider.js
-front_end/extensions/ExtensionView.js
-front_end/browser_sdk/browser_sdk.js
-front_end/browser_sdk/LogManager.js
-front_end/persistence/persistence.js
-front_end/persistence/WorkspaceSettingsTab.js
-front_end/persistence/PlatformFileSystem.js
-front_end/persistence/PersistenceUtils.js
-front_end/persistence/PersistenceImpl.js
-front_end/persistence/PersistenceActions.js
-front_end/persistence/NetworkPersistenceManager.js
-front_end/persistence/IsolatedFileSystemManager.js
-front_end/persistence/IsolatedFileSystem.js
-front_end/persistence/FileSystemWorkspaceBinding.js
-front_end/persistence/EditFileSystemView.js
-front_end/persistence/Automapping.js
-front_end/components/components.js
-front_end/components/TargetDetachedDialog.js
-front_end/components/Reload.js
-front_end/components/Linkifier.js
-front_end/components/JSPresentationUtils.js
-front_end/components/ImagePreview.js
-front_end/components/DockController.js
-front_end/bindings/bindings.js
-front_end/bindings/TempFile.js
-front_end/bindings/StylesSourceMapping.js
-front_end/bindings/SASSSourceMapping.js
-front_end/bindings/ResourceUtils.js
-front_end/bindings/ResourceScriptMapping.js
-front_end/bindings/ResourceMapping.js
-front_end/bindings/PresentationConsoleMessageHelper.js
-front_end/bindings/NetworkProject.js
-front_end/bindings/LiveLocation.js
-front_end/bindings/FileUtils.js
-front_end/bindings/DefaultScriptMapping.js
-front_end/bindings/DebuggerWorkspaceBinding.js
-front_end/bindings/CSSWorkspaceBinding.js
-front_end/bindings/ContentProviderBasedProject.js
-front_end/bindings/CompilerScriptMapping.js
-front_end/bindings/BreakpointManager.js
-front_end/bindings/BlackboxManager.js
-front_end/workspace/workspace.js
-front_end/workspace/WorkspaceImpl.js
-front_end/workspace/UISourceCode.js
-front_end/workspace/FileManager.js
-front_end/services/services.js
-front_end/services/ServiceManager.js
-front_end/sdk/sdk.js
-front_end/sdk/TracingModel.js
-front_end/sdk/TracingManager.js
-front_end/sdk/TargetManager.js
-front_end/sdk/Target.js
-front_end/sdk/SourceMapManager.js
-front_end/sdk/SourceMap.js
-front_end/sdk/ServiceWorkerManager.js
-front_end/sdk/ServiceWorkerCacheModel.js
-front_end/sdk/ServerTiming.js
-front_end/sdk/SecurityOriginManager.js
-front_end/sdk/SDKModel.js
-front_end/sdk/Script.js
-front_end/sdk/ScreenCaptureModel.js
-front_end/sdk/RuntimeModel.js
-front_end/sdk/ResourceTreeModel.js
-front_end/sdk/Resource.js
-front_end/sdk/RemoteObject.js
-front_end/sdk/ProfileTreeModel.js
-front_end/sdk/IssuesModel.js
-front_end/sdk/PerformanceMetricsModel.js
-front_end/sdk/PaintProfiler.js
-front_end/sdk/OverlayModel.js
-front_end/sdk/NetworkRequest.js
-front_end/sdk/NetworkManager.js
-front_end/sdk/NetworkLog.js
-front_end/sdk/LogModel.js
-front_end/sdk/LayerTreeBase.js
-front_end/sdk/IsolateManager.js
-front_end/sdk/HeapProfilerModel.js
-front_end/sdk/HARLog.js
-front_end/sdk/FilmStripModel.js
-front_end/sdk/EmulationModel.js
-front_end/sdk/DOMModel.js
-front_end/sdk/DOMDebuggerModel.js
-front_end/sdk/DebuggerModel.js
-front_end/sdk/CSSStyleSheetHeader.js
-front_end/sdk/CSSStyleDeclaration.js
-front_end/sdk/CSSRule.js
-front_end/sdk/CSSProperty.js
-front_end/sdk/CSSModel.js
-front_end/sdk/CSSMetadata.js
-front_end/sdk/CSSMedia.js
-front_end/sdk/CSSMatchedStyles.js
-front_end/sdk/CPUProfilerModel.js
-front_end/sdk/CPUProfileDataModel.js
-front_end/sdk/CookieParser.js
-front_end/sdk/CookieModel.js
-front_end/sdk/CompilerSourceMappingContentProvider.js
-front_end/sdk/ConsoleModel.js
-front_end/sdk/Connections.js
-front_end/sdk/ChildTargetManager.js
-front_end/protocol/protocol.js
-front_end/protocol/NodeURL.js
-front_end/protocol/InspectorBackend.js
-front_end/host/host.js
-front_end/host/UserMetrics.js
-front_end/host/ResourceLoader.js
-front_end/host/Platform.js
-front_end/host/InspectorFrontendHost.js
-front_end/host/InspectorFrontendHostAPI.js
-front_end/dom_extension/DOMExtension.js
-front_end/dom_extension/dom_extension.js
-front_end/root.js
-front_end/Runtime.js
-front_end/platform/utilities.js
-front_end/platform/platform.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ZoomManager.js
-front_end/ui/XWidget.js
-front_end/ui/XLink.js
-front_end/ui/XElement.js
-front_end/ui/Widget.js
-front_end/ui/View.js
-front_end/ui/ViewManager.js
-front_end/ui/UIUtils.js
-front_end/ui/ui.js
-front_end/ui/Treeoutline.js
-front_end/ui/Tooltip.js
-front_end/ui/Toolbar.js
-front_end/ui/ThrottledWidget.js
-front_end/ui/TextPrompt.js
-front_end/ui/TextEditor.js
-front_end/ui/TargetCrashedScreen.js
-front_end/ui/TabbedPane.js
-front_end/ui/SyntaxHighlighter.js
-front_end/ui/SuggestBox.js
-front_end/ui/SplitWidget.js
-front_end/ui/SoftDropDown.js
-front_end/ui/SoftContextMenu.js
-front_end/ui/ShortcutsScreen.js
-front_end/ui/ShortcutRegistry.js
-front_end/ui/SettingsUI.js
-front_end/ui/SegmentedButton.js
-front_end/ui/SearchableView.js
-front_end/ui/RootView.js
-front_end/ui/ResizerWidget.js
-front_end/ui/ReportView.js
-front_end/ui/RemoteDebuggingTerminatedScreen.js
-front_end/ui/ProgressIndicator.js
-front_end/ui/PopoverHelper.js
-front_end/ui/Panel.js
-front_end/ui/ListWidget.js
-front_end/ui/ListModel.js
-front_end/ui/ListControl.js
-front_end/ui/KeyboardShortcut.js
-front_end/ui/InspectorView.js
-front_end/ui/InplaceEditor.js
-front_end/ui/Infobar.js
-front_end/ui/Icon.js
-front_end/ui/HistoryInput.js
-front_end/ui/GlassPane.js
-front_end/ui/Geometry.js
-front_end/ui/Fragment.js
-front_end/ui/ForwardedInputEventHandler.js
-front_end/ui/FilterSuggestionBuilder.js
-front_end/ui/FilterBar.js
-front_end/ui/EmptyWidget.js
-front_end/ui/DropTarget.js
-front_end/ui/Dialog.js
-front_end/ui/ContextMenu.js
-front_end/ui/Context.js
-front_end/ui/ARIAUtils.js
-front_end/ui/ActionRegistry.js
-front_end/ui/Action.js
-front_end/ui/ActionDelegate.js
-front_end/ui/ContextFlavorListener.js
-front_end/root.js
-front_end/common/common.js
-front_end/common/common-legacy.js
-front_end/common/App.js
-front_end/common/AppProvider.js
-front_end/common/CharacterIdMap.js
-front_end/common/Color.js
-front_end/common/ContentProvider.js
-front_end/common/EventTarget.js
-front_end/common/JavaScriptMetaData.js
-front_end/common/Linkifier.js
-front_end/common/Object.js
-front_end/common/Console.js
-front_end/common/ParsedURL.js
-front_end/common/Progress.js
-front_end/common/QueryParamHandler.js
-front_end/common/ResourceType.js
-front_end/common/Revealer.js
-front_end/common/Runnable.js
-front_end/common/SegmentedRange.js
-front_end/common/Settings.js
-front_end/common/StaticContentProvider.js
-front_end/common/StringOutputStream.js
-front_end/common/TextDictionary.js
-front_end/common/Throttler.js
-front_end/common/Trie.js
-front_end/common/UIString.js
-front_end/common/Worker.js
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index 7554005..8154cc1 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -76,8 +76,6 @@
       tick_clock_(base::DefaultTickClock::GetInstance()),
       timing_(new PerformanceTiming(clock, time_origin_)),
       memory_(new MemoryInfo()),
-      lifecycle_timing_(
-          new PerformanceLifecycleTiming("lifecycle timing", time_origin_)),
       resource_timing_buffer_size_limit_(
           Performance::kMaxResourceTimingBufferSize),
       resource_timing_buffer_current_size_(0),
@@ -87,6 +85,8 @@
       add_to_performance_entry_buffer_flag_(false) {
   unix_at_zero_monotonic_ = GetUnixAtZeroMonotonic(
       base::DefaultClock::GetInstance(), tick_clock_);
+  lifecycle_timing_ = base::MakeRefCounted<PerformanceLifecycleTiming>(
+      "lifecycle timing", time_origin());
   QueuePerformanceEntry(lifecycle_timing_);
 }
 
diff --git a/src/cobalt/dom/performance_high_resolution_time.h b/src/cobalt/dom/performance_high_resolution_time.h
index 5033e5b..0684e41 100644
--- a/src/cobalt/dom/performance_high_resolution_time.h
+++ b/src/cobalt/dom/performance_high_resolution_time.h
@@ -39,7 +39,7 @@
   return (time - base::TimeTicks()).InMillisecondsF();
 }
 
-// Clamp customized minimum clock resolution.
+// Clamp customized minimum clock resolution in milliseconds.
 //   https://w3c.github.io/hr-time/#clock-resolution
 inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(
     base::TimeTicks ticks,
@@ -49,13 +49,13 @@
         (microseconds % min_resolution_in_microseconds)).InMillisecondsF();
 }
 
-// Clamp customized minimum clock resolution.
+// Clamp customized minimum clock resolution in milliseconds.
 //   https://w3c.github.io/hr-time/#clock-resolution
 inline DOMHighResTimeStamp ClampTimeStampMinimumResolution(base::TimeDelta delta,
     int64_t min_resolution_in_microseconds) {
     int64_t microseconds = delta.InMicroseconds();
     return base::TimeDelta::FromMicroseconds(microseconds -
-        (microseconds % min_resolution_in_microseconds)).InMicrosecondsF();
+        (microseconds % min_resolution_in_microseconds)).InMillisecondsF();
 }
 
 }  // namespace dom
diff --git a/src/cobalt/dom/performance_lifecycle_timing.cc b/src/cobalt/dom/performance_lifecycle_timing.cc
index 08f47d4..f09fee0 100644
--- a/src/cobalt/dom/performance_lifecycle_timing.cc
+++ b/src/cobalt/dom/performance_lifecycle_timing.cc
@@ -41,23 +41,22 @@
   }
 
     DOMHighResTimeStamp ConvertSbTimeMonotonicToDOMHiResTimeStamp(
-      base::TimeTicks time_origin, SbTimeMonotonic monotonic_time) {
+      const DOMHighResTimeStamp time_origin, SbTimeMonotonic monotonic_time) {
     SbTimeMonotonic time_delta = SbTimeGetNow() - SbTimeGetMonotonicNow();
     base::Time base_time = base::Time::FromSbTime(time_delta + monotonic_time);
     base::TimeTicks time_ticks =
         base::TimeTicks::FromInternalValue(static_cast<int64_t>(
             base_time.ToJsTime()));
-    return Performance::MonotonicTimeToDOMHighResTimeStamp(
-        time_origin, time_ticks);
+    return ClampTimeStampMinimumResolution(time_ticks,
+        Performance::kPerformanceTimerMinResolutionInMicroseconds) - time_origin;
   }
 
 }  // namespace
 
 PerformanceLifecycleTiming::PerformanceLifecycleTiming(
-    const std::string& name, base::TimeTicks time_origin)
+    const std::string& name, const DOMHighResTimeStamp time_origin)
     : PerformanceEntry(name, 0.0, 0.0), time_origin_(time_origin) {}
 
-
 DOMHighResTimeStamp PerformanceLifecycleTiming::app_preload() const {
   return ReportDOMHighResTimeStamp(lifecycle_timing_info_.app_preload);
 }
diff --git a/src/cobalt/dom/performance_lifecycle_timing.h b/src/cobalt/dom/performance_lifecycle_timing.h
index 9baa10c..01e3c79 100644
--- a/src/cobalt/dom/performance_lifecycle_timing.h
+++ b/src/cobalt/dom/performance_lifecycle_timing.h
@@ -31,7 +31,7 @@
 class PerformanceLifecycleTiming : public PerformanceEntry {
  public:
   PerformanceLifecycleTiming(const std::string& name,
-                             base::TimeTicks time_origin);
+                             const DOMHighResTimeStamp time_origin);
 
   // Web API.
   DOMHighResTimeStamp app_preload() const;
@@ -83,7 +83,7 @@
 
   LifecycleTimingInfo lifecycle_timing_info_;
 
-  base::TimeTicks time_origin_;
+  DOMHighResTimeStamp time_origin_;
 
   DISALLOW_COPY_AND_ASSIGN(PerformanceLifecycleTiming);
 };
diff --git a/src/cobalt/extension/platform_service.h b/src/cobalt/extension/platform_service.h
index 1d85cc9..4b66e86 100644
--- a/src/cobalt/extension/platform_service.h
+++ b/src/cobalt/extension/platform_service.h
@@ -42,7 +42,7 @@
 
 // When a client receives a message from a service, the service will be passed
 // in as the |context| here, with |data|, which has length |length|.
-typedef void (*ReceiveMessageCallback)(void* context, void* data,
+typedef void (*ReceiveMessageCallback)(void* context, const void* data,
                                        uint64_t length);
 
 typedef struct CobaltExtensionPlatformServiceApi {
diff --git a/src/cobalt/h5vcc/h5vcc_platform_service.cc b/src/cobalt/h5vcc/h5vcc_platform_service.cc
index f744176..8462103 100644
--- a/src/cobalt/h5vcc/h5vcc_platform_service.cc
+++ b/src/cobalt/h5vcc/h5vcc_platform_service.cc
@@ -14,6 +14,9 @@
 
 #include "cobalt/h5vcc/h5vcc_platform_service.h"
 
+#include <utility>
+#include <vector>
+
 #include "cobalt/base/polymorphic_downcast.h"
 #include "cobalt/dom/dom_settings.h"
 #include "starboard/common/string.h"
@@ -117,17 +120,23 @@
 }
 
 // static
-void H5vccPlatformService::Receive(void* context, void* data, uint64_t length) {
+void H5vccPlatformService::Receive(void* context, const void* data,
+                                   uint64_t length) {
   DCHECK(context) << "Platform should not call Receive with NULL context";
-  static_cast<H5vccPlatformService*>(context)->ReceiveInternal(data, length);
+  // Make a copy of the data before potentially crossing thread boundaries,
+  // since we don't have any guarantee of the lifetime of the given data.
+  const uint8_t* input_data = static_cast<const uint8_t*>(data);
+  std::vector<uint8_t> internal_data(input_data, input_data + length);
+  static_cast<H5vccPlatformService*>(context)->ReceiveInternal(
+      std::move(internal_data));
 }
 
-void H5vccPlatformService::ReceiveInternal(void* data, uint64_t length) {
+void H5vccPlatformService::ReceiveInternal(std::vector<uint8_t> data) {
   // ReceiveInternal may be called by another thread.
   if (!main_message_loop_->BelongsToCurrentThread()) {
     main_message_loop_->PostTask(
         FROM_HERE, base::Bind(&H5vccPlatformService::ReceiveInternal,
-                              weak_this_, data, length));
+                              weak_this_, std::move(data)));
     return;
   }
   DCHECK(main_message_loop_->BelongsToCurrentThread());
@@ -136,10 +145,11 @@
     return;
   }
   script::Handle<script::ArrayBuffer> data_array_buffer;
-  if (length) {
-    data_array_buffer = script::ArrayBuffer::New(environment_, data, length);
-  } else {
+  if (data.empty()) {
     data_array_buffer = script::ArrayBuffer::New(environment_, 0);
+  } else {
+    data_array_buffer =
+        script::ArrayBuffer::New(environment_, data.data(), data.size());
   }
 
   const scoped_refptr<H5vccPlatformService>& service(this);
diff --git a/src/cobalt/h5vcc/h5vcc_platform_service.h b/src/cobalt/h5vcc/h5vcc_platform_service.h
index 1a86286..62ac3e1 100644
--- a/src/cobalt/h5vcc/h5vcc_platform_service.h
+++ b/src/cobalt/h5vcc/h5vcc_platform_service.h
@@ -17,6 +17,7 @@
 
 #include <map>
 #include <string>
+#include <vector>
 
 #include "base/message_loop/message_loop.h"
 #include "base/optional.h"
@@ -65,9 +66,9 @@
  private:
   static constexpr size_t kMaxNameLength = 1024;
 
-  void ReceiveInternal(void* data, uint64_t length);
+  void ReceiveInternal(std::vector<uint8_t> data);
 
-  static void Receive(void* context, void* data, uint64_t length);
+  static void Receive(void* context, const void* data, uint64_t length);
 
   bool IsOpen();
 
diff --git a/src/cobalt/layout_tests/layout_tests.cc b/src/cobalt/layout_tests/layout_tests.cc
index 028de65..1f25893 100644
--- a/src/cobalt/layout_tests/layout_tests.cc
+++ b/src/cobalt/layout_tests/layout_tests.cc
@@ -128,9 +128,8 @@
   // room for tests to maneuver within and speed at which pixel tests can be
   // done.
   const ViewportSize kDefaultViewportSize(640, 360);
-  ViewportSize viewport_size = test_info.viewport_size
-                                   ? *test_info.viewport_size
-                                   : kDefaultViewportSize;
+  ViewportSize viewport_size =
+      test_info.viewport_size ? *test_info.viewport_size : kDefaultViewportSize;
 
   renderer::RenderTreePixelTester pixel_tester(
       viewport_size.width_height(), GetTestInputRootDirectory(),
@@ -222,30 +221,26 @@
 }
 
 // Cobalt-specific test cases.
-INSTANTIATE_TEST_CASE_P(
-    CobaltSpecificLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("cobalt")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CobaltSpecificLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("cobalt")),
+                        GetTestName());
 // Custom CSS 2.1 (https://www.w3.org/TR/CSS21/) test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSS21LayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css-2-1")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSS21LayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("css-2-1")),
+                        GetTestName());
 // Custom CSS Background (https://www.w3.org/TR/css3-background/) test cases.
 INSTANTIATE_TEST_CASE_P(
     CSSBackground3LayoutTests, Layout,
     ::testing::ValuesIn(EnumerateLayoutTests("css3-background")),
     GetTestName());
 // Custom CSS Color (https://www.w3.org/TR/css3-color/) test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSSColor3LayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css3-color")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSSColor3LayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("css3-color")),
+                        GetTestName());
 // Custom CSS Images (https://www.w3.org/TR/css3-images/) test cases.
 INSTANTIATE_TEST_CASE_P(
     CSSImages3LayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css3-images")),
-    GetTestName());
+    ::testing::ValuesIn(EnumerateLayoutTests("css3-images")), GetTestName());
 // Custom CSS Media Queries (https://www.w3.org/TR/css3-mediaqueries/) test
 // cases.
 INSTANTIATE_TEST_CASE_P(
@@ -253,16 +248,14 @@
     ::testing::ValuesIn(EnumerateLayoutTests("css3-mediaqueries")),
     GetTestName());
 // Custom CSS Text (https://www.w3.org/TR/css-text-3/) test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSSText3LayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css-text-3")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSSText3LayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("css-text-3")),
+                        GetTestName());
 // Custom CSS Transform (http://https://www.w3.org/TR/css-transforms/)
 // test cases.
 INSTANTIATE_TEST_CASE_P(
     CSSTransformsLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css-transforms")),
-    GetTestName());
+    ::testing::ValuesIn(EnumerateLayoutTests("css-transforms")), GetTestName());
 // Custom CSS Transition
 // (https://www.w3.org/TR/2013/WD-css3-transitions-20131119/)
 // test cases.
@@ -279,15 +272,13 @@
     GetTestName());
 // Custom bidi text (http://www.unicode.org/reports/tr9/)
 // (https://www.w3.org/TR/CSS21/visuren.html#direction) test cases.
-INSTANTIATE_TEST_CASE_P(
-    BidiLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("bidi")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(BidiLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("bidi")),
+                        GetTestName());
 // Custom text shaping test cases.
 INSTANTIATE_TEST_CASE_P(
     TextShapingLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("text-shaping")),
-    GetTestName());
+    ::testing::ValuesIn(EnumerateLayoutTests("text-shaping")), GetTestName());
 // Custom CSS Conditional (https://www.w3.org/TR/css3-conditional/) test cases.
 INSTANTIATE_TEST_CASE_P(
     CSSConditional3LayoutTests, Layout,
@@ -298,25 +289,22 @@
     CSSFlexbox3LayoutTests, Layout,
     ::testing::ValuesIn(EnumerateLayoutTests("css3-flexbox")), GetTestName());
 // Custom CSS Font (https://www.w3.org/TR/css3-fonts/) test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSS3FontsLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css3-fonts")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSS3FontsLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("css3-fonts")),
+                        GetTestName());
 // Custom CSS Text Decor (https://www.w3.org/TR/css-text-decor-3/) test cases.
 INSTANTIATE_TEST_CASE_P(
     CSS3TextDecorLayoutTests, Layout,
     ::testing::ValuesIn(EnumerateLayoutTests("css3-text-decor")),
     GetTestName());
 // Custom CSS UI (https://www.w3.org/TR/css3-ui/) test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSS3UILayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css3-ui")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSS3UILayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("css3-ui")),
+                        GetTestName());
 // Custom CSS Value (https://www.w3.org/TR/css3-values/) test cases.
 INSTANTIATE_TEST_CASE_P(
     CSS3ValuesLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("css3-values")),
-    GetTestName());
+    ::testing::ValuesIn(EnumerateLayoutTests("css3-values")), GetTestName());
 // Custom incremental layout test cases.
 INSTANTIATE_TEST_CASE_P(
     IncrementalLayoutLayoutTests, Layout,
@@ -324,10 +312,9 @@
     GetTestName());
 // Custom CSSOM view (https://www.w3.org/TR/2013/WD-cssom-view-20131217/)
 // test cases.
-INSTANTIATE_TEST_CASE_P(
-    CSSOMViewLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("cssom-view")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(CSSOMViewLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("cssom-view")),
+                        GetTestName());
 // Custom DOM (https://dom.spec.whatwg.org/) test cases.
 INSTANTIATE_TEST_CASE_P(DOMLayoutTests, Layout,
                         ::testing::ValuesIn(EnumerateLayoutTests("dom")),
@@ -341,11 +328,9 @@
 
 // JavaScript HTML5 WebAPIs (https://www.w3.org/TR/html50/webappapis.html) test
 // cases.
-INSTANTIATE_TEST_CASE_P(
-    WebAppAPIsLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("webappapis")),
-    GetTestName());
-
+INSTANTIATE_TEST_CASE_P(WebAppAPIsLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("webappapis")),
+                        GetTestName());
 // JavaScript HTML5 APIs that describe requestAnimationFrame().
 //   https://www.w3.org/TR/animation-timing/
 INSTANTIATE_TEST_CASE_P(
@@ -356,8 +341,7 @@
 // Problematic test cases found through cluster-fuzz.
 INSTANTIATE_TEST_CASE_P(
     ClusterFuzzLayoutTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("cluster-fuzz")),
-    GetTestName());
+    ::testing::ValuesIn(EnumerateLayoutTests("cluster-fuzz")), GetTestName());
 
 // Intersection Observer API (https://www.w3.org/TR/intersection-observer/) test
 // cases
@@ -366,6 +350,11 @@
     ::testing::ValuesIn(EnumerateLayoutTests("intersection-observer")),
     GetTestName());
 
+// webp background image test cases.
+INSTANTIATE_TEST_CASE_P(WebPLayoutTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("webp")),
+                        GetTestName());
+
 // Blitter does not support Skottie.
 #if !SB_HAS(BLITTER)
 // Lottie (https://github.com/LottieFiles/lottie-player) test cases
@@ -377,17 +366,14 @@
 // Disable on Windows until network stack is implemented.
 #if !defined(COBALT_WIN)
 // Content Security Policy test cases.
-INSTANTIATE_TEST_CASE_P(
-    ContentSecurityPolicyTests, Layout,
-    ::testing::ValuesIn(EnumerateLayoutTests("csp")),
-    GetTestName());
+INSTANTIATE_TEST_CASE_P(ContentSecurityPolicyTests, Layout,
+                        ::testing::ValuesIn(EnumerateLayoutTests("csp")),
+                        GetTestName());
 #endif  // !defined(COBALT_WIN)
 
 // Pixel-perfect tests.
 INSTANTIATE_TEST_CASE_P(
     CobaltPixelTests, LayoutExact,
-    ::testing::ValuesIn(EnumerateLayoutTests("cobalt-pixel")),
-    GetTestName());
-
+    ::testing::ValuesIn(EnumerateLayoutTests("cobalt-pixel")), GetTestName());
 }  // namespace layout_tests
 }  // namespace cobalt
diff --git a/src/cobalt/layout_tests/testdata/webp/layout_tests.txt b/src/cobalt/layout_tests/testdata/webp/layout_tests.txt
new file mode 100644
index 0000000..a7b4e0c
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/webp/layout_tests.txt
@@ -0,0 +1 @@
+static-webp-background-image
diff --git a/src/cobalt/layout_tests/testdata/webp/static-webp-background-image-expected.png b/src/cobalt/layout_tests/testdata/webp/static-webp-background-image-expected.png
new file mode 100644
index 0000000..edcc28c
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/webp/static-webp-background-image-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/webp/static-webp-background-image.html b/src/cobalt/layout_tests/testdata/webp/static-webp-background-image.html
new file mode 100644
index 0000000..92d307b
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/webp/static-webp-background-image.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!--
+ | This test checks if a static webp background image is rendered as expected.
+ -->
+<html>
+
+<head>
+    <style>
+        div {
+            height: 360px;
+            width: 480px;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            window.testRunner.waitUntilDone();
+        }
+
+        var image = new Image();
+        var image_name = 'static-webp-image.webp';
+
+        image.onload = function () {
+            var cobalt = document.getElementById('image');
+            cobalt.style.background = 'url(' + image_name + ')';
+
+            if (window.testRunner) {
+                window.testRunner.notifyDone();
+            }
+        }
+
+        image.src = image_name;
+
+    </script>
+</head>
+
+<body>
+    <div id='image'></div>
+</body>
+
+</html>
diff --git a/src/cobalt/layout_tests/testdata/webp/static-webp-image.webp b/src/cobalt/layout_tests/testdata/webp/static-webp-image.webp
new file mode 100644
index 0000000..cca0a37
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/webp/static-webp-image.webp
Binary files differ
diff --git a/src/cobalt/media_integration_tests/endurance/endurance_test.py b/src/cobalt/media_integration_tests/endurance/endurance_test.py
index 302519d..18cc902 100644
--- a/src/cobalt/media_integration_tests/endurance/endurance_test.py
+++ b/src/cobalt/media_integration_tests/endurance/endurance_test.py
@@ -155,11 +155,11 @@
       app.Resume()
 
     actions = {
-      'PlayPause': lambda _app: _app.PlayOrPause(),
-      'Fastforward': lambda _app: _app.Fastforward(),
-      'Rewind': lambda _app: _app.Rewind(),
-      'PlayPrevious': lambda _app: _app.PlayPrevious(),
-      'PlayNext': lambda _app: _app.PlayNext(),
+        'PlayPause': lambda _app: _app.PlayOrPause(),
+        'Fastforward': lambda _app: _app.Fastforward(),
+        'Rewind': lambda _app: _app.Rewind(),
+        'PlayPrevious': lambda _app: _app.PlayPrevious(),
+        'PlayNext': lambda _app: _app.PlayNext(),
     }
     if TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME):
       actions['SuspendAndResume'] = SuspendAndResume
@@ -259,6 +259,6 @@
         if current_running_time - self.last_action_time > IDLE_TIME_MAXIMUM:
           # Play the previous playback again.
           app.PlayPrevious()
-          self.playback_start_time = -1
+          self.last_action_time = current_running_time
 
       app.RemovePlayerStateChangeHandler(self.OnPlayerStateChanged)
diff --git a/src/cobalt/media_session/media_session_client.cc b/src/cobalt/media_session/media_session_client.cc
index 1a18649..99097ef 100644
--- a/src/cobalt/media_session/media_session_client.cc
+++ b/src/cobalt/media_session/media_session_client.cc
@@ -33,6 +33,9 @@
 // Delay to re-query position state after an action has been invoked.
 const base::TimeDelta kUpdateDelay = base::TimeDelta::FromMilliseconds(250);
 
+// Delay to check if the media session state is not active.
+const base::TimeDelta kMaybeFreezeDelay = base::TimeDelta::FromMilliseconds(1500);
+
 // Guess the media position state for the media session.
 void GuessMediaPositionState(MediaSessionState* session_state,
                              const media::WebMediaPlayer** guess_player,
@@ -67,7 +70,8 @@
 
 MediaSessionClient::MediaSessionClient(MediaSession* media_session)
     : media_session_(media_session),
-      platform_playback_state_(kMediaSessionPlaybackStateNone) {
+      platform_playback_state_(kMediaSessionPlaybackStateNone),
+      sequence_number_(0) {
   extension_ = static_cast<const CobaltExtensionMediaSessionApi*>(
       SbSystemGetExtension(kCobaltExtensionMediaSessionName));
   if (extension_) {
@@ -186,6 +190,17 @@
     UpdateMediaSessionState();
   }
 
+  if (!is_active()) {
+    media_session_->task_runner_->PostDelayedTask(
+        FROM_HERE, base::Bind(&MediaSessionClient::RunMaybeFreezeCallback,
+                              base::Unretained(this), ++sequence_number_),
+                              kMaybeFreezeDelay);
+  }
+}
+
+void MediaSessionClient::RunMaybeFreezeCallback(int sequence_number) {
+  if (sequence_number != sequence_number_) return;
+
   if (!is_active() && !maybe_freeze_callback_.is_null()) {
     maybe_freeze_callback_.Run();
   }
diff --git a/src/cobalt/media_session/media_session_client.h b/src/cobalt/media_session/media_session_client.h
index 3e37d1f..115b852 100644
--- a/src/cobalt/media_session/media_session_client.h
+++ b/src/cobalt/media_session/media_session_client.h
@@ -95,6 +95,10 @@
     media_session_ = media_session;
   }
 
+  // If the media session is not active, then run MaybeFreezeCallback to
+  // suspend the App.
+  void RunMaybeFreezeCallback(int sequence_number);
+
  private:
   THREAD_CHECKER(thread_checker_);
   MediaSession* media_session_;
@@ -133,6 +137,10 @@
 
   base::Closure maybe_freeze_callback_;
 
+  // This is for checking the sequence number of PostDelayedTask. It should be
+  // aligned with a single thread.
+  int sequence_number_;
+
   DISALLOW_COPY_AND_ASSIGN(MediaSessionClient);
 };
 
diff --git a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
index a9305ef..076aaf8 100644
--- a/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
+++ b/src/cobalt/renderer/rasterizer/egl/textured_mesh_renderer.cc
@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "cobalt/extension/graphics.h"
 #include "cobalt/math/size.h"
@@ -364,28 +365,31 @@
       graphics_extension->GetMapToMeshColorAdjustments(&color_adjustment)) {
     // Setup vectors for the color adjustments. Ensure they use dot for decimal
     // point regardless of locale.
-    std::stringstream buffer;
-    buffer.imbue(std::locale::classic());
-    buffer << "  vec4 scale0 = vec4(" << color_adjustment.rgba0_scale[0] << ","
-           << color_adjustment.rgba0_scale[1] << ","
-           << color_adjustment.rgba0_scale[2] << ","
-           << color_adjustment.rgba0_scale[3] << ");";
-    buffer << "  vec4 scale1 = vec4(" << color_adjustment.rgba1_scale[0] << ","
-           << color_adjustment.rgba1_scale[1] << ","
-           << color_adjustment.rgba1_scale[2] << ","
-           << color_adjustment.rgba1_scale[3] << ");";
-    buffer << "  vec4 scale2 = vec4(" << color_adjustment.rgba2_scale[0] << ","
-           << color_adjustment.rgba2_scale[1] << ","
-           << color_adjustment.rgba2_scale[2] << ","
-           << color_adjustment.rgba2_scale[3] << ");";
-    buffer << "  vec4 scale3 = vec4(" << color_adjustment.rgba3_scale[0] << ","
-           << color_adjustment.rgba3_scale[1] << ","
-           << color_adjustment.rgba3_scale[2] << ","
-           << color_adjustment.rgba3_scale[3] << ");";
+    std::string buffer;
+    buffer = "  vec4 scale0 = vec4(" +
+             base::NumberToString(color_adjustment.rgba0_scale[0]) + "," +
+             base::NumberToString(color_adjustment.rgba0_scale[1]) + "," +
+             base::NumberToString(color_adjustment.rgba0_scale[2]) + "," +
+             base::NumberToString(color_adjustment.rgba0_scale[3]) + ");" +
+             "  vec4 scale1 = vec4(" +
+             base::NumberToString(color_adjustment.rgba1_scale[0]) + "," +
+             base::NumberToString(color_adjustment.rgba1_scale[1]) + "," +
+             base::NumberToString(color_adjustment.rgba1_scale[2]) + "," +
+             base::NumberToString(color_adjustment.rgba1_scale[3]) + ");" +
+             "  vec4 scale2 = vec4(" +
+             base::NumberToString(color_adjustment.rgba2_scale[0]) + "," +
+             base::NumberToString(color_adjustment.rgba2_scale[1]) + "," +
+             base::NumberToString(color_adjustment.rgba2_scale[2]) + "," +
+             base::NumberToString(color_adjustment.rgba2_scale[3]) + ");" +
+             "  vec4 scale3 = vec4(" +
+             base::NumberToString(color_adjustment.rgba3_scale[0]) + "," +
+             base::NumberToString(color_adjustment.rgba3_scale[1]) + "," +
+             base::NumberToString(color_adjustment.rgba3_scale[2]) + "," +
+             base::NumberToString(color_adjustment.rgba3_scale[3]) + ");";
     blit_fragment_shader_source +=
         "  vec4 color2 = color * color;"
         "  vec4 color3 = color2 * color;" +
-        buffer.str() +
+        buffer +
         "  color = scale0 + scale1*color + scale2*color2 + scale3*color3;"
         "  gl_FragColor = clamp(color, vec4(0.0), vec4(1.0));"
         "}";
diff --git a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
index dfefca6..5fe1b23 100644
--- a/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
+++ b/src/cobalt/renderer/rasterizer/skia/skia/skia.gyp
@@ -28,6 +28,7 @@
       'target_name': 'skia_library',
       'type': 'static_library',
       'dependencies': [
+        '<(DEPTH)/base/base.gyp:base',
         'skia_library_no_asan',
       ],
       'includes': [
@@ -65,7 +66,6 @@
       'target_name': 'filter_fuzz_stub',
       'type': 'executable',
       'dependencies': [
-        '<(DEPTH)/base/base.gyp:base',
         'skia',
       ],
       'sources': [
diff --git a/src/cobalt/site/docs/development/setup-android.md b/src/cobalt/site/docs/development/setup-android.md
index 61849d8..f999d81 100644
--- a/src/cobalt/site/docs/development/setup-android.md
+++ b/src/cobalt/site/docs/development/setup-android.md
@@ -9,7 +9,7 @@
 ## Preliminary Setup
 
 <aside class="note">
-<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.md">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
+<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.html">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
 </aside>
 
 1.  Additional build dependencies may need to be installed:
@@ -224,7 +224,9 @@
 run that on a device, it needs to be packaged into an APK, which is done by the
 associated "deploy" target (e.g. nplb_deploy). The Starboard test runner does
 all this for you, so just use that to build and run tests. For example, to
-build and run "devel" NPLB on an ARM64 device, from the top 'src' directory:
+build and run "devel" NPLB on an ARM64 device, from the top 'src' directory
+(if you've unnested the 'src' directory, just run this from your top-level
+directory):
 
 ```
 starboard/tools/testing/test_runner.py -p android-arm64 -c devel -b -r -t nplb
diff --git a/src/cobalt/site/docs/development/setup-linux.md b/src/cobalt/site/docs/development/setup-linux.md
index 6b9df7e..9e40a3e 100644
--- a/src/cobalt/site/docs/development/setup-linux.md
+++ b/src/cobalt/site/docs/development/setup-linux.md
@@ -55,10 +55,29 @@
     $ git clone https://cobalt.googlesource.com/cobalt
     ```
 
+### Set up Developer Tools
+
+Cobalt's developer tools require a different file structure which we are in the
+process of moving to. For now, if you want to use these tools, you must unnest
+the `src/` directory like so:
+
+```
+$ cd cobalt
+$ git mv src/* ./
+$ git mv src/.* ./
+```
+
+Once you do that, you'll be able to follow the following two steps to have C++
+and Python linting and formatting as well as other helpful checks enabled. Keep
+in mind that after doing this, you'll want to run following commands in the
+top-level directory instead of the `src/` subdirectory.
+
+Git will track this as a large change, we recommend that you create a commit
+for it and rebase that commit of our upstream continuously for now.
+
 1.  Create a Python 3 virtual environment for working on Cobalt (feel free to use `virtualenvwrapper` instead):
 
     ```
-    $ cd cobalt
     $ python -m venv ~/.virtualenvs/cobalt_dev
     $ source ~/.virtualenvs/cobalt_dev
     $ pip install -r requirements.txt
diff --git a/src/cobalt/site/docs/development/setup-raspi.md b/src/cobalt/site/docs/development/setup-raspi.md
index 75d43cc..0e58a7d 100644
--- a/src/cobalt/site/docs/development/setup-raspi.md
+++ b/src/cobalt/site/docs/development/setup-raspi.md
@@ -54,7 +54,7 @@
 ## Set up your workstation
 
 <aside class="note">
-<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.md">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
+<b>Note:</b> Before proceeding further, refer to the documentation for <a href="setup-linux.html">"Set up your environment - Linux"</a>. Complete the section **Set up your workstation**, then return and complete the following steps.
 </aside>
 
 The following steps install the cross-compiling toolchain on your workstation.
@@ -106,6 +106,11 @@
 
 ## Build, install, and run Cobalt for Raspberry Pi
 
+<aside class="note">
+<b>Note:</b> If you've unnested the 'src' directory, build and compile the code
+in your top-level checkout of Cobalt instead of the 'src' subdirectory.
+</aside>
+
 1.  Build the code by navigating to the src directory in your cobalt directory and run the
     following command :
 
diff --git a/src/cobalt/site/docs/reference/starboard/modules/13/media.md b/src/cobalt/site/docs/reference/starboard/modules/13/media.md
index 9b4d7bb..6b46874 100644
--- a/src/cobalt/site/docs/reference/starboard/modules/13/media.md
+++ b/src/cobalt/site/docs/reference/starboard/modules/13/media.md
@@ -682,24 +682,6 @@
 bool SbMediaIsBufferUsingMemoryPool()
 ```
 
-### SbMediaIsSupported ###
-
-Indicates whether this platform supports decoding `video_codec` and
-`audio_codec` along with decrypting using `key_system`. If `video_codec` is
-`kSbMediaVideoCodecNone` or if `audio_codec` is `kSbMediaAudioCodecNone`, this
-function should return `true` as long as `key_system` is supported on the
-platform to decode any supported input formats.
-
-`video_codec`: The `SbMediaVideoCodec` being checked for platform compatibility.
-`audio_codec`: The `SbMediaAudioCodec` being checked for platform compatibility.
-`key_system`: The key system being checked for platform compatibility.
-
-#### Declaration ####
-
-```
-bool SbMediaIsSupported(SbMediaVideoCodec video_codec, SbMediaAudioCodec audio_codec, const char *key_system)
-```
-
 ### SbMediaSetAudioWriteDuration ###
 
 Communicate to the platform how far past `current_playback_position` the app
diff --git a/src/cobalt/site/docs/reference/starboard/modules/media.md b/src/cobalt/site/docs/reference/starboard/modules/media.md
index 4ad1e16..6b46874 100644
--- a/src/cobalt/site/docs/reference/starboard/modules/media.md
+++ b/src/cobalt/site/docs/reference/starboard/modules/media.md
@@ -682,12 +682,6 @@
 bool SbMediaIsBufferUsingMemoryPool()
 ```
 
-#### Declaration ####
-
-```
-bool SbMediaIsSupported(SbMediaVideoCodec video_codec, SbMediaAudioCodec audio_codec, const char *key_system)
-```
-
 ### SbMediaSetAudioWriteDuration ###
 
 Communicate to the platform how far past `current_playback_position` the app
diff --git a/src/docker-compose.yml b/src/docker-compose.yml
index 19374ed..8b1437b 100644
--- a/src/docker-compose.yml
+++ b/src/docker-compose.yml
@@ -363,6 +363,13 @@
       PLATFORM: linux-x64x11-sbversion-12
       CONFIG: ${CONFIG:-debug}
 
+  # Example usage of unittest:
+  # 1. Build the containers for which you want to unittest
+  # docker-compose up --build --no-start linux-x64x11 unittest
+  # 2. Build the 'all' target for the platform you want to test
+  # PLATFORM=linux-x64x11 CONFIG=devel TARGET=all docker-compose run linux-x64x11
+  # 3. Run the unittests for that target.
+  # PLATFORM=linux-x64x11 CONFIG=devel TARGET=all docker-compose run unittest
   unittest:
     <<: *common-definitions
     build:
diff --git a/src/docker/linux/android/Dockerfile b/src/docker/linux/android/Dockerfile
index 020a826..535b10d 100644
--- a/src/docker/linux/android/Dockerfile
+++ b/src/docker/linux/android/Dockerfile
@@ -18,11 +18,7 @@
     && apt install -qqy --no-install-recommends \
         default-jdk \
         g++-multilib \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 RUN mkdir -p /root/.android
 
diff --git a/src/docker/linux/base/Dockerfile b/src/docker/linux/base/Dockerfile
index f7e49f2..9cdc8f8 100644
--- a/src/docker/linux/base/Dockerfile
+++ b/src/docker/linux/base/Dockerfile
@@ -14,7 +14,9 @@
 
 ARG BASE_OS
 ARG BASE_OS_TAG
-FROM ${BASE_OS:-gcr.io/cloud-marketplace-containers/google/debian9}:${BASE_OS_TAG:-latest}
+FROM ${BASE_OS:-gcr.io/cloud-marketplace-containers/google/debian10}:${BASE_OS_TAG:-latest}
+
+COPY base/clean-after-apt.sh /opt/clean-after-apt.sh
 
 ENV PYTHONUNBUFFERED 1
 
@@ -28,11 +30,7 @@
         python3-pip \
         python3-requests \
         git ccache \
-        curl \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+        curl xz-utils \
+    && /opt/clean-after-apt.sh
 
 CMD ["/usr/bin/python","--version"]
diff --git a/src/docker/linux/base/build/Dockerfile b/src/docker/linux/base/build/Dockerfile
index 0de107d..390b969 100644
--- a/src/docker/linux/base/build/Dockerfile
+++ b/src/docker/linux/base/build/Dockerfile
@@ -26,11 +26,7 @@
         pkgconf \
         unzip \
         yasm \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 # === Get Nodejs pinned LTS version via NVM
 ARG NVM_SHA256SUM="f068e17dacb88f73302790cc076956c7a0d459ce9b01df842ff3e75744f9e2fe /tmp/install.sh"
diff --git a/src/docker/linux/base/clean-after-apt.sh b/src/docker/linux/base/clean-after-apt.sh
new file mode 100755
index 0000000..c408d58
--- /dev/null
+++ b/src/docker/linux/base/clean-after-apt.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+apt-get clean autoclean
+apt-get autoremove -y --purge
+rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+rm -rf /var/lib/{apt,cache,log}
+echo "Cleaned and purged apt temporaries."
diff --git a/src/docker/linux/clang-3-9/Dockerfile b/src/docker/linux/clang-3-9/Dockerfile
index af62c51..97bab91 100644
--- a/src/docker/linux/clang-3-9/Dockerfile
+++ b/src/docker/linux/clang-3-9/Dockerfile
@@ -18,11 +18,7 @@
 
 RUN apt update -qqy \
     && apt install -qqy --no-install-recommends clang-3.9 \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 CMD /code/cobalt/build/gyp_cobalt -v -C ${CONFIG} ${PLATFORM} && \
     ccache -z && \
diff --git a/src/docker/linux/evergreen/Dockerfile b/src/docker/linux/evergreen/Dockerfile
index 9880a55a..21223d5 100644
--- a/src/docker/linux/evergreen/Dockerfile
+++ b/src/docker/linux/evergreen/Dockerfile
@@ -21,11 +21,7 @@
         binutils-aarch64-linux-gnu \
         binutils-arm-linux-gnueabi \
         g++-multilib \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 CMD /code/cobalt/build/gyp_cobalt -v -C ${CONFIG:-debug} ${PLATFORM} && \
     ninja -v -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG:-debug} ${TARGET:-cobalt_deploy}
diff --git a/src/docker/linux/linux-x64x11/Dockerfile b/src/docker/linux/linux-x64x11/Dockerfile
index 3e8c8dc..816203b 100644
--- a/src/docker/linux/linux-x64x11/Dockerfile
+++ b/src/docker/linux/linux-x64x11/Dockerfile
@@ -27,11 +27,7 @@
         libxrender-dev \
         libxcomposite-dev \
         libxi-dev \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 CMD /code/cobalt/build/gyp_cobalt -v -C ${CONFIG} ${PLATFORM} && \
     ninja -v -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG} ${TARGET:-cobalt_deploy}
diff --git a/src/docker/linux/raspi/Dockerfile b/src/docker/linux/raspi/Dockerfile
index e4f7f01..c5d800d 100644
--- a/src/docker/linux/raspi/Dockerfile
+++ b/src/docker/linux/raspi/Dockerfile
@@ -28,11 +28,7 @@
         libxml2 \
         binutils-aarch64-linux-gnu \
         binutils-arm-linux-gnueabi \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 # Get the combined toolchains package.
 RUN cd /tmp \
diff --git a/src/docker/linux/stub/Dockerfile b/src/docker/linux/stub/Dockerfile
index bf96e84..0237a7c 100644
--- a/src/docker/linux/stub/Dockerfile
+++ b/src/docker/linux/stub/Dockerfile
@@ -14,20 +14,19 @@
 
 FROM cobalt-build-base
 
+# Using clang in the deps here to correctly resolve the appropriate libstdc++.
+# Previously this specifically pulled in libstdc++6-dev which is no longer
+# available since we updated the base image to Debian 10 / Buster.
 RUN apt update -qqy \
     && apt install -qqy --no-install-recommends \
-        libstdc++-6-dev \
+        clang \
         mesa-common-dev \
         libx11-dev \
         libxcomposite-dev \
         libxrender-dev \
         libasound2-dev \
-        libxml2 \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+        libxml2-dev \
+    && /opt/clean-after-apt.sh
 
 CMD /code/cobalt/build/gyp_cobalt -v -C ${CONFIG} ${PLATFORM} && \
     ninja -v -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG} ${TARGET:-cobalt_deploy}
diff --git a/src/docker/linux/unittest/Dockerfile b/src/docker/linux/unittest/Dockerfile
index c833335..45b65f1 100644
--- a/src/docker/linux/unittest/Dockerfile
+++ b/src/docker/linux/unittest/Dockerfile
@@ -17,10 +17,10 @@
 RUN apt update -qqy \
     && apt install -qqy --no-install-recommends \
         libasound2 \
-        libavcodec57 \
-        libavformat57 \
-        libavresample3 \
-        libavutil55 \
+        libavcodec-dev \
+        libavformat-dev \
+        libavresample-dev \
+        libavutil-dev \
         libegl1-mesa \
         libgl1-mesa-dri \
         libgles2-mesa \
@@ -30,14 +30,9 @@
         unzip \
         xauth \
         xvfb \
-    && apt-get clean autoclean \
-    && apt-get autoremove -y --purge \
-    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
-    && rm -rf /var/lib/{apt,dpkg,cache,log} \
-    && echo "Done"
+    && /opt/clean-after-apt.sh
 
 WORKDIR /out
-
 # Sets the locale in the environment. This is needed for NPLB unit tests.
 ENV LANG en_US.UTF-8
 
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
index 0e1d66b..18418e8 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.media.AudioAttributes;
+import android.media.AudioDeviceCallback;
 import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
 import android.media.AudioManager;
@@ -29,12 +30,16 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /** Creates and destroys AudioTrackBridge and handles the volume change. */
 public class AudioOutputManager implements CobaltMediaSession.UpdateVolumeListener {
   private List<AudioTrackBridge> audioTrackBridgeList;
   private Context context;
 
+  AtomicBoolean hasAudioDeviceChanged = new AtomicBoolean(false);
+  boolean hasRegisteredAudioDeviceCallback = false;
+
   public AudioOutputManager(Context context) {
     this.context = context;
     audioTrackBridgeList = new ArrayList<AudioTrackBridge>();
@@ -54,7 +59,7 @@
       int sampleRate,
       int channelCount,
       int preferredBufferSizeInBytes,
-      boolean enableAudioRouting,
+      boolean enableAudioDeviceCallback,
       int tunnelModeAudioSessionId) {
     AudioTrackBridge audioTrackBridge =
         new AudioTrackBridge(
@@ -62,13 +67,58 @@
             sampleRate,
             channelCount,
             preferredBufferSizeInBytes,
-            enableAudioRouting,
             tunnelModeAudioSessionId);
     if (!audioTrackBridge.isAudioTrackValid()) {
       Log.e(TAG, "AudioTrackBridge has invalid audio track");
       return null;
     }
     audioTrackBridgeList.add(audioTrackBridge);
+    hasAudioDeviceChanged.set(false);
+
+    if (Build.VERSION.SDK_INT < 23
+        || hasRegisteredAudioDeviceCallback
+        || !enableAudioDeviceCallback) {
+      return audioTrackBridge;
+    }
+
+    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+    audioManager.registerAudioDeviceCallback(
+        new AudioDeviceCallback() {
+          // Since registering a callback triggers an immediate call to onAudioDevicesAdded() with
+          // current devices, don't set |hasAudioDeviceChanged| for this initial call.
+          private boolean initialDevicesAdded = false;
+
+          private void handleConnectedDeviceChange(AudioDeviceInfo[] devices) {
+            for (AudioDeviceInfo info : devices) {
+              // TODO: Determine if AudioDeviceInfo.TYPE_HDMI_EARC should be checked in API 31.
+              if (info.isSink()
+                  && (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
+                      || info.getType() == AudioDeviceInfo.TYPE_HDMI_ARC
+                      || info.getType() == AudioDeviceInfo.TYPE_HDMI)) {
+                // TODO: Avoid destroying the AudioTrack if the new devices can support the current
+                // AudioFormat.
+                hasAudioDeviceChanged.set(true);
+                break;
+              }
+            }
+          }
+
+          @Override
+          public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            if (initialDevicesAdded) {
+              handleConnectedDeviceChange(addedDevices);
+              return;
+            }
+            initialDevicesAdded = true;
+          }
+
+          @Override
+          public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            handleConnectedDeviceChange(removedDevices);
+          }
+        },
+        null);
+    hasRegisteredAudioDeviceCallback = true;
     return audioTrackBridge;
   }
 
@@ -307,50 +357,95 @@
               encoding, Build.VERSION.SDK_INT));
       return false;
     }
-    if (hasPassthroughSupportForV23(encoding)) {
+
+    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+    AudioDeviceInfo[] deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+
+    // Some devices have issues on reporting playback capability and managing routing when Bluetooth
+    // output is connected.  So e/ac3 support is disabled when Bluetooth output device is connected.
+    for (AudioDeviceInfo info : deviceInfos) {
+      if (info.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) {
+        Log.i(
+            TAG,
+            String.format(
+                "Passthrough on encoding %d is disabled because Bluetooth output device is"
+                    + " connected.",
+                encoding));
+        return false;
+      }
+    }
+
+    // Sample rate is not provided when the function is called, assume it is 48000.
+    final int DEFAULT_SURROUND_SAMPLE_RATE = 48000;
+
+    if (hasPassthroughSupportForV23(deviceInfos, encoding)) {
       Log.i(
           TAG,
           String.format(
               "Passthrough on encoding %d is supported, as hasPassthroughSupportForV23() returns"
                   + " true.",
               encoding));
-      return true;
-    }
-    if (Build.VERSION.SDK_INT < 29) {
-      Log.i(
-          TAG,
-          String.format(
-              "Passthrough on encoding %d is rejected, as"
-                  + " hasDirectSurroundingPlaybackSupportForV29() is not called for api %d.",
-              encoding, Build.VERSION.SDK_INT));
-      return false;
-    }
-    if (hasDirectSurroundingPlaybackSupportForV29(encoding)) {
-      Log.i(
-          TAG,
-          String.format(
-              "Passthrough on encoding %d is supported, as"
-                  + " hasDirectSurroundingPlaybackSupportForV29() returns true.",
-              encoding));
-      return true;
+    } else {
+      if (Build.VERSION.SDK_INT < 29) {
+        Log.i(
+            TAG,
+            String.format(
+                "Passthrough on encoding %d is rejected, as"
+                    + " hasDirectSurroundPlaybackSupportForV29() is not called for api %d.",
+                encoding, Build.VERSION.SDK_INT));
+        return false;
+      }
+      if (hasDirectSurroundPlaybackSupportForV29(encoding, DEFAULT_SURROUND_SAMPLE_RATE)) {
+        Log.i(
+            TAG,
+            String.format(
+                "Passthrough on encoding %d is supported, as"
+                    + " hasDirectSurroundPlaybackSupportForV29() returns true.",
+                encoding));
+      } else {
+        Log.i(
+            TAG,
+            String.format(
+                "Passthrough on encoding %d is not supported, as"
+                    + " hasDirectSurroundPlaybackSupportForV29() returns false.",
+                encoding));
+        return false;
+      }
     }
 
-    Log.i(
-        TAG,
-        String.format(
-            "Passthrough on encoding %d is not supported, as"
-                + " hasDirectSurroundingPlaybackSupportForV29() returns false.",
-            encoding));
-    return false;
+    Log.i(TAG, "Verify passthrough support by creating an AudioTrack.");
+
+    try {
+      AudioTrack audioTrack =
+          new AudioTrack(
+              getDefaultAudioAttributes(),
+              getPassthroughAudioFormatFor(encoding, DEFAULT_SURROUND_SAMPLE_RATE),
+              AudioTrack.getMinBufferSize(48000, AudioFormat.CHANNEL_OUT_5POINT1, encoding),
+              AudioTrack.MODE_STREAM,
+              AudioManager.AUDIO_SESSION_ID_GENERATE);
+      audioTrack.release();
+    } catch (Exception e) {
+      // AudioTrack creation can fail if the audio is routed to an unexpected device. For example,
+      // when the user has Bluetooth headphones connected, or when the encoding is EAC3 and both
+      // HDMI and SPDIF are connected, where the output should fallback to AC3.
+      Log.w(
+          TAG,
+          String.format(
+              "Passthrough on encoding %d is disabled because creating AudioTrack raises"
+                  + " exception: ",
+              encoding),
+          e);
+      return false;
+    }
+
+    Log.i(TAG, "AudioTrack creation succeeded, passthrough support verified.");
+
+    return true;
   }
 
   /** Returns whether passthrough on `encoding` is supported for API 23 and above. */
   @RequiresApi(23)
-  private boolean hasPassthroughSupportForV23(int encoding) {
-    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-    AudioDeviceInfo[] deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
-
-    // TODO: Verify the follow code returns false if non-surrounding BT device is routed.
+  private boolean hasPassthroughSupportForV23(final AudioDeviceInfo[] deviceInfos, int encoding) {
     for (AudioDeviceInfo info : deviceInfos) {
       final int type = info.getType();
       if (type != AudioDeviceInfo.TYPE_HDMI && type != AudioDeviceInfo.TYPE_HDMI_ARC) {
@@ -394,39 +489,50 @@
   }
 
   @RequiresApi(29)
-  /**
-   * Returns whether direct playback on surrounding `encoding` is supported for API 29 and above.
-   */
-  private boolean hasDirectSurroundingPlaybackSupportForV29(int encoding) {
+  /** Returns whether direct playback on surround `encoding` is supported for API 29 and above. */
+  private boolean hasDirectSurroundPlaybackSupportForV29(int encoding, int sampleRate) {
     if (encoding != AudioFormat.ENCODING_AC3
         && encoding != AudioFormat.ENCODING_E_AC3
         && encoding != AudioFormat.ENCODING_E_AC3_JOC) {
       Log.w(
           TAG,
           String.format(
-              "hasDirectSurroundingPlaybackSupportForV29() encountered unsupported encoding %d.",
+              "hasDirectSurroundPlaybackSupportForV29() encountered unsupported encoding %d.",
               encoding));
       return false;
     }
 
-    // Sample rate is not provided when the function is called, assume it is 48000.
-    final int DEFAULT_SURROUNDING_SAMPLE_RATE = 48000;
-    AudioFormat format =
-        new AudioFormat.Builder()
-            .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
-            .setEncoding(encoding)
-            .setSampleRate(DEFAULT_SURROUNDING_SAMPLE_RATE)
-            .build();
-    AudioAttributes attributes =
-        new AudioAttributes.Builder()
-            .setUsage(AudioAttributes.USAGE_MEDIA)
-            .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
-            .build();
-    final boolean supported = AudioTrack.isDirectPlaybackSupported(format, attributes);
+    boolean supported =
+        AudioTrack.isDirectPlaybackSupported(
+            getPassthroughAudioFormatFor(encoding, sampleRate), getDefaultAudioAttributes());
     Log.i(
         TAG,
         String.format(
             "isDirectPlaybackSupported() for encoding %d returned %b.", encoding, supported));
     return supported;
   }
+
+  // TODO: Move utility functions into a separate class.
+  /** Returns AudioFormat for surround `encoding` and `sampleRate`. */
+  static AudioFormat getPassthroughAudioFormatFor(int encoding, int sampleRate) {
+    return new AudioFormat.Builder()
+        .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
+        .setEncoding(encoding)
+        .setSampleRate(sampleRate)
+        .build();
+  }
+
+  /** Returns default AudioAttributes for surround playbacks. */
+  static AudioAttributes getDefaultAudioAttributes() {
+    // TODO: Turn this into a static variable after it is moved into a separate class.
+    return new AudioAttributes.Builder()
+        .setUsage(AudioAttributes.USAGE_MEDIA)
+        .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
+        .build();
+  }
+
+  @UsedByNative
+  private boolean getAndResetHasAudioDeviceChanged() {
+    return hasAudioDeviceChanged.getAndSet(false);
+  }
 }
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
index 7441984..0001fde 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java
@@ -17,11 +17,8 @@
 import static dev.cobalt.media.Log.TAG;
 
 import android.media.AudioAttributes;
-import android.media.AudioDeviceInfo;
 import android.media.AudioFormat;
 import android.media.AudioManager;
-import android.media.AudioRouting;
-import android.media.AudioRouting.OnRoutingChangedListener;
 import android.media.AudioTimestamp;
 import android.media.AudioTrack;
 import android.os.Build;
@@ -30,8 +27,6 @@
 import dev.cobalt.util.UsedByNative;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * A wrapper of the android AudioTrack class. Android AudioTrack would not start playing until the
@@ -51,10 +46,6 @@
   private ByteBuffer avSyncHeader;
   private int avSyncPacketBytesRemaining;
 
-  private AtomicBoolean newAudioDeviceAdded = new AtomicBoolean(false);
-  private AudioDeviceInfo currentRoutedDevice;
-  private OnRoutingChangedListener onRoutingChangedListener;
-
   private static int getBytesPerSample(int audioFormat) {
     switch (audioFormat) {
       case AudioFormat.ENCODING_PCM_16BIT:
@@ -73,10 +64,7 @@
       int sampleRate,
       int channelCount,
       int preferredBufferSizeInBytes,
-      boolean enableAudioRouting,
       int tunnelModeAudioSessionId) {
-    // TODO: Re-enable audio routing when all related bugs are fixed.
-    enableAudioRouting = false;
 
     tunnelModeEnabled = tunnelModeAudioSessionId != -1;
     int channelConfig;
@@ -121,15 +109,15 @@
               .build();
     } else {
       // TODO: Support ENCODING_E_AC3_JOC for api level 28 or later.
-      final boolean is_surrounding =
+      final boolean is_surround =
           sampleType == AudioFormat.ENCODING_AC3 || sampleType == AudioFormat.ENCODING_E_AC3;
-      // TODO: We start to enforce |CONTENT_TYPE_MOVIE| for surrounding playback, investigate if we
-      //       can use |CONTENT_TYPE_MOVIE| for all non-surrounding AudioTrack used by video
+      // TODO: We start to enforce |CONTENT_TYPE_MOVIE| for surround playback, investigate if we
+      //       can use |CONTENT_TYPE_MOVIE| for all non-surround AudioTrack used by video
       //       playback.
       attributes =
           new AudioAttributes.Builder()
               .setContentType(
-                  is_surrounding
+                  is_surround
                       ? AudioAttributes.CONTENT_TYPE_MOVIE
                       : AudioAttributes.CONTENT_TYPE_MUSIC)
               .setUsage(AudioAttributes.USAGE_MEDIA)
@@ -176,31 +164,6 @@
             audioTrackBufferSize,
             preferredBufferSizeInBytes,
             AudioTrack.getMinBufferSize(sampleRate, channelConfig, sampleType)));
-    if (audioTrack != null && enableAudioRouting && Build.VERSION.SDK_INT >= 24) {
-      Log.i(TAG, "Audio routing enabled.");
-      currentRoutedDevice = audioTrack.getRoutedDevice();
-      onRoutingChangedListener =
-          new AudioRouting.OnRoutingChangedListener() {
-            @Override
-            public void onRoutingChanged(AudioRouting router) {
-              AudioDeviceInfo newRoutedDevice = router.getRoutedDevice();
-              if (currentRoutedDevice == null && newRoutedDevice != null) {
-                if (!areAudioDevicesEqual(currentRoutedDevice, newRoutedDevice)) {
-                  Log.v(
-                      TAG,
-                      String.format(
-                          "New audio device %s added to AudioTrackAudioSink.",
-                          newRoutedDevice.getProductName()));
-                  newAudioDeviceAdded.set(true);
-                }
-              }
-              currentRoutedDevice = newRoutedDevice;
-            }
-          };
-      audioTrack.addOnRoutingChangedListener(onRoutingChangedListener, null);
-    } else {
-      Log.i(TAG, "Audio routing disabled.");
-    }
   }
 
   public Boolean isAudioTrackValid() {
@@ -209,9 +172,6 @@
 
   public void release() {
     if (audioTrack != null) {
-      if (Build.VERSION.SDK_INT >= 24 && onRoutingChangedListener != null) {
-        audioTrack.removeOnRoutingChangedListener(onRoutingChangedListener);
-      }
       audioTrack.release();
     }
     audioTrack = null;
@@ -424,26 +384,4 @@
     }
     return audioTrack.getUnderrunCount();
   }
-
-  @RequiresApi(23)
-  private boolean areAudioDevicesEqual(AudioDeviceInfo device1, AudioDeviceInfo device2) {
-    if (device1.getId() == device2.getId()
-        && device1.getType() == device2.getType()
-        && device1.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
-      // This is a workaround for the emulator, which triggers an error callback when switching
-      // between devices with different hash codes that are otherwise identical.
-      return Arrays.equals(device1.getChannelCounts(), device2.getChannelCounts())
-          && Arrays.equals(device1.getChannelIndexMasks(), device2.getChannelIndexMasks())
-          && Arrays.equals(device1.getChannelMasks(), device2.getChannelMasks())
-          && Arrays.equals(device1.getEncodings(), device2.getEncodings())
-          && Arrays.equals(device1.getSampleRates(), device2.getSampleRates())
-          && device1.getProductName().equals(device2.getProductName());
-    }
-    return device1.equals(device2);
-  }
-
-  @UsedByNative
-  private boolean getAndResetHasNewAudioDeviceAdded() {
-    return newAudioDeviceAdded.getAndSet(false);
-  }
 }
diff --git a/src/starboard/android/arm/platform_configuration/configuration.gni b/src/starboard/android/arm/platform_configuration/configuration.gni
index 92e7a77..a4cf9ff 100644
--- a/src/starboard/android/arm/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm/platform_configuration/configuration.gni
@@ -15,4 +15,5 @@
 import("//starboard/android/shared/platform_configuration/configuration.gni")
 
 android_abi = "armeabi-v7a"
+arm_version = 7
 sabi_path = "//starboard/sabi/arm/softfp/sabi-v$sb_api_version.json"
diff --git a/src/starboard/android/arm64/platform_configuration/configuration.gni b/src/starboard/android/arm64/platform_configuration/configuration.gni
index 13ca22c..efade93 100644
--- a/src/starboard/android/arm64/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm64/platform_configuration/configuration.gni
@@ -15,4 +15,5 @@
 import("//starboard/android/shared/platform_configuration/configuration.gni")
 
 android_abi = "arm64-v8a"
+arm_version = 8
 sabi_path = "//starboard/sabi/arm64/sabi-v$sb_api_version.json"
diff --git a/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni b/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
index c6d6f73..b90be0f 100644
--- a/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
+++ b/src/starboard/android/arm64/vulkan/platform_configuration/configuration.gni
@@ -15,6 +15,7 @@
 import("//starboard/android/shared/platform_configuration/configuration.gni")
 
 android_abi = "arm64-v8a"
+arm_version = 8
 sabi_path = "//starboard/sabi/arm64/sabi-v$sb_api_version.json"
 
 enable_vulkan = true
diff --git a/src/starboard/android/shared/audio_renderer_passthrough.cc b/src/starboard/android/shared/audio_renderer_passthrough.cc
index 4f2820d..1f0849c 100644
--- a/src/starboard/android/shared/audio_renderer_passthrough.cc
+++ b/src/starboard/android/shared/audio_renderer_passthrough.cc
@@ -34,8 +34,6 @@
 constexpr SbTime kAudioTrackUpdateInternal = kSbTimeMillisecond * 5;
 
 constexpr int kPreferredBufferSizeInBytes = 16 * 1024;
-// TODO: Enable audio routing and link it to client side experiment.
-constexpr bool kEnableAudioRouting = false;
 // TODO: Enable passthrough with tunnel mode.
 constexpr int kTunnelModeAudioSessionId = -1;
 
@@ -75,8 +73,10 @@
 
 AudioRendererPassthrough::AudioRendererPassthrough(
     const SbMediaAudioSampleInfo& audio_sample_info,
-    SbDrmSystem drm_system)
-    : audio_sample_info_(audio_sample_info) {
+    SbDrmSystem drm_system,
+    bool enable_audio_device_callback)
+    : audio_sample_info_(audio_sample_info),
+      enable_audio_device_callback_(enable_audio_device_callback) {
   SB_DCHECK(audio_sample_info_.codec == kSbMediaAudioCodecAc3 ||
             audio_sample_info_.codec == kSbMediaAudioCodecEac3);
   if (SbDrmSystemIsValid(drm_system)) {
@@ -384,7 +384,7 @@
       optional<SbMediaAudioSampleType>(),  // Not required in passthrough mode
       audio_sample_info_.number_of_channels,
       audio_sample_info_.samples_per_second, kPreferredBufferSizeInBytes,
-      kEnableAudioRouting, kTunnelModeAudioSessionId));
+      enable_audio_device_callback_, kTunnelModeAudioSessionId));
 
   if (!audio_track_bridge->is_valid()) {
     error_cb_(kSbPlayerErrorDecode, "Error creating AudioTrackBridge");
@@ -436,6 +436,16 @@
   SB_DCHECK(error_cb_);
   SB_DCHECK(audio_track_bridge_);
 
+  if (enable_audio_device_callback_ &&
+      audio_track_bridge_->GetAndResetHasAudioDeviceChanged()) {
+    SB_LOG(INFO) << "Audio device changed, raising a capability changed error "
+                    "to restart playback.";
+    error_cb_(kSbPlayerErrorCapabilityChanged,
+              "Audio device capability changed");
+    audio_track_bridge_->PauseAndFlush();
+    return;
+  }
+
   AudioTrackState current_state;
 
   {
@@ -499,15 +509,21 @@
           sample_buffer, samples_to_write, sync_time);
       // Error code returned as negative value, like kAudioTrackErrorDeadObject.
       if (samples_written < 0) {
-        // `kSbPlayerErrorDecode` is used for general SbPlayer error, there is
-        // no error code corresponding to audio sink.
-        auto error = kSbPlayerErrorDecode;
         if (samples_written == AudioTrackBridge::kAudioTrackErrorDeadObject) {
           // Inform the audio end point change.
-          error = kSbPlayerErrorCapabilityChanged;
+          SB_LOG(INFO)
+              << "Write error for dead audio track, audio device capability "
+                 "has likely changed. Restarting playback.";
+          error_cb_(kSbPlayerErrorCapabilityChanged,
+                    "Audio device capability changed");
+          audio_track_bridge_->PauseAndFlush();
+          return;
         }
-        error_cb_(error, FormatString("Error while writing frames: %d",
-                                      samples_written));
+        // `kSbPlayerErrorDecode` is used for general SbPlayer error, there is
+        // no error code corresponding to audio sink.
+        error_cb_(
+            kSbPlayerErrorDecode,
+            FormatString("Error while writing frames: %d", samples_written));
       }
       decoded_audio_writing_offset_ += samples_written;
 
diff --git a/src/starboard/android/shared/audio_renderer_passthrough.h b/src/starboard/android/shared/audio_renderer_passthrough.h
index 6d9a050..58a073c 100644
--- a/src/starboard/android/shared/audio_renderer_passthrough.h
+++ b/src/starboard/android/shared/audio_renderer_passthrough.h
@@ -49,7 +49,8 @@
       private ::starboard::shared::starboard::player::JobQueue::JobOwner {
  public:
   AudioRendererPassthrough(const SbMediaAudioSampleInfo& audio_sample_info,
-                           SbDrmSystem drm_system);
+                           SbDrmSystem drm_system,
+                           bool enable_audio_device_callback);
   ~AudioRendererPassthrough() override;
 
   bool is_valid() const { return decoder_ != nullptr; }
@@ -96,8 +97,9 @@
   void OnDecoderConsumed();
   void OnDecoderOutput();
 
-  // The following two variables are set in the ctor.
+  // The following three variables are set in the ctor.
   const SbMediaAudioSampleInfo audio_sample_info_;
+  const bool enable_audio_device_callback_;
   // The AudioDecoder is used as a decryptor when the stream is encrypted.
   // TODO: Revisit to encapsulate the AudioDecoder as a SbDrmSystemPrivate
   //       instead.  This would need to turn SbDrmSystemPrivate::Decrypt() into
diff --git a/src/starboard/android/shared/audio_track_audio_sink_type.cc b/src/starboard/android/shared/audio_track_audio_sink_type.cc
index 4c46710..57e9aed 100644
--- a/src/starboard/android/shared/audio_track_audio_sink_type.cc
+++ b/src/starboard/android/shared/audio_track_audio_sink_type.cc
@@ -82,7 +82,7 @@
     SbAudioSinkPrivate::ErrorFunc error_func,
     SbTime start_time,
     int tunnel_mode_audio_session_id,
-    bool enable_audio_routing,
+    bool enable_audio_device_callback,
     void* context)
     : type_(type),
       channels_(channels),
@@ -105,7 +105,7 @@
               channels,
               sampling_frequency_hz,
               preferred_buffer_size_in_bytes,
-              enable_audio_routing,
+              enable_audio_device_callback,
               tunnel_mode_audio_session_id) {
   SB_DCHECK(update_source_status_func_);
   SB_DCHECK(consume_frames_func_);
@@ -178,10 +178,11 @@
   while (!quit_) {
     int playback_head_position = 0;
     SbTime frames_consumed_at = 0;
-    if (bridge_.GetAndResetHasNewAudioDeviceAdded(env)) {
-      SB_LOG(INFO) << "New audio device added.";
-      error_func_(kSbPlayerErrorCapabilityChanged, "New audio device added.",
-                  context_);
+    if (bridge_.GetAndResetHasAudioDeviceChanged(env)) {
+      SB_LOG(INFO) << "Audio device changed, raising a capability changed "
+                      "error to restart playback.";
+      error_func_(kSbPlayerErrorCapabilityChanged,
+                  "Audio device capability changed", context_);
       break;
     }
 
@@ -328,6 +329,7 @@
           capabilities_changed,
           FormatString("Error while writing frames: %d", written_frames),
           context_);
+      SB_LOG(INFO) << "Restarting playback.";
       break;
     } else if (written_frames > 0) {
       last_written_succeeded_at = now;
@@ -418,13 +420,15 @@
     SbAudioSinkPrivate::ErrorFunc error_func,
     void* context) {
   const SbTime kStartTime = 0;
-  const int kTunnelModeAudioSessionId = -1;  // disable tunnel mode
-  const bool kEnableAudioRouting = true;
+  // Disable tunnel mode.
+  const int kTunnelModeAudioSessionId = -1;
+  // Disable AudioDeviceCallback for WebAudio.
+  const bool kEnableAudioDeviceCallback = false;
   return Create(channels, sampling_frequency_hz, audio_sample_type,
                 audio_frame_storage_type, frame_buffers, frames_per_channel,
                 update_source_status_func, consume_frames_func, error_func,
-                kStartTime, kTunnelModeAudioSessionId, kEnableAudioRouting,
-                context);
+                kStartTime, kTunnelModeAudioSessionId,
+                kEnableAudioDeviceCallback, context);
 }
 
 SbAudioSink AudioTrackAudioSinkType::Create(
@@ -439,7 +443,7 @@
     SbAudioSinkPrivate::ErrorFunc error_func,
     SbTime start_media_time,
     int tunnel_mode_audio_session_id,
-    bool enable_audio_routing,
+    bool enable_audio_device_callback,
     void* context) {
   int min_required_frames = SbAudioSinkGetMinBufferSizeInFrames(
       channels, audio_sample_type, sampling_frequency_hz);
@@ -450,8 +454,8 @@
       this, channels, sampling_frequency_hz, audio_sample_type, frame_buffers,
       frames_per_channel, preferred_buffer_size_in_bytes,
       update_source_status_func, consume_frames_func, error_func,
-      start_media_time, tunnel_mode_audio_session_id, enable_audio_routing,
-      context);
+      start_media_time, tunnel_mode_audio_session_id,
+      enable_audio_device_callback, context);
   if (!audio_sink->IsAudioTrackValid()) {
     SB_DLOG(ERROR)
         << "AudioTrackAudioSinkType::Create failed to create audio track";
diff --git a/src/starboard/android/shared/audio_track_audio_sink_type.h b/src/starboard/android/shared/audio_track_audio_sink_type.h
index 5ae9f7b..adf050d 100644
--- a/src/starboard/android/shared/audio_track_audio_sink_type.h
+++ b/src/starboard/android/shared/audio_track_audio_sink_type.h
@@ -68,7 +68,7 @@
       SbAudioSinkPrivate::ErrorFunc error_func,
       SbTime start_time,
       int tunnel_mode_audio_session_id,
-      bool enable_audio_routing,
+      bool enable_audio_device_callback,
       void* context);
 
   bool IsValid(SbAudioSink audio_sink) override {
@@ -111,7 +111,7 @@
       SbAudioSinkPrivate::ErrorFunc error_func,
       SbTime start_media_time,
       int tunnel_mode_audio_session_id,
-      bool enable_audio_routing,
+      bool enable_audio_device_callback,
       void* context);
   ~AudioTrackAudioSink() override;
 
diff --git a/src/starboard/android/shared/audio_track_bridge.cc b/src/starboard/android/shared/audio_track_bridge.cc
index 572e759..79fe83f 100644
--- a/src/starboard/android/shared/audio_track_bridge.cc
+++ b/src/starboard/android/shared/audio_track_bridge.cc
@@ -39,7 +39,7 @@
                                    int channels,
                                    int sampling_frequency_hz,
                                    int preferred_buffer_size_in_bytes,
-                                   bool enable_audio_routing,
+                                   bool enable_audio_device_callback,
                                    int tunnel_mode_audio_session_id) {
   if (coding_type == kSbMediaAudioCodingTypePcm) {
     SB_DCHECK(SbAudioSinkIsAudioSampleTypeSupported(sample_type.value()));
@@ -65,7 +65,7 @@
       j_audio_output_manager.Get(), "createAudioTrackBridge",
       "(IIIIZI)Ldev/cobalt/media/AudioTrackBridge;",
       GetAudioFormatSampleType(coding_type, sample_type), sampling_frequency_hz,
-      channels, preferred_buffer_size_in_bytes, enable_audio_routing,
+      channels, preferred_buffer_size_in_bytes, enable_audio_device_callback,
       tunnel_mode_audio_session_id);
   if (!j_audio_track_bridge) {
     // One of the cases that this may hit is when output happened to be switched
@@ -272,13 +272,17 @@
                                   "J");
 }
 
-bool AudioTrackBridge::GetAndResetHasNewAudioDeviceAdded(
+bool AudioTrackBridge::GetAndResetHasAudioDeviceChanged(
     JniEnvExt* env /*= JniEnvExt::Get()*/) {
   SB_DCHECK(env);
   SB_DCHECK(is_valid());
 
+  ScopedLocalJavaRef<jobject> j_audio_output_manager(
+      env->CallStarboardObjectMethodOrAbort(
+          "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
+
   return env->CallBooleanMethodOrAbort(
-      j_audio_track_bridge_, "getAndResetHasNewAudioDeviceAdded", "()Z");
+      j_audio_output_manager.Get(), "getAndResetHasAudioDeviceChanged", "()Z");
 }
 
 int AudioTrackBridge::GetUnderrunCount(JniEnvExt* env /*= JniEnvExt::Get()*/) {
diff --git a/src/starboard/android/shared/audio_track_bridge.h b/src/starboard/android/shared/audio_track_bridge.h
index e18e498..607837d 100644
--- a/src/starboard/android/shared/audio_track_bridge.h
+++ b/src/starboard/android/shared/audio_track_bridge.h
@@ -41,7 +41,7 @@
                    int channels,
                    int sampling_frequency_hz,
                    int preferred_buffer_size_in_bytes,
-                   bool enable_audio_routing,
+                   bool enable_audio_device_callback,
                    int tunnel_mode_audio_session_id);
   ~AudioTrackBridge();
 
@@ -79,7 +79,7 @@
   // updated on return.  It can be nullptr.
   int64_t GetPlaybackHeadPosition(SbTime* updated_at,
                                   JniEnvExt* env = JniEnvExt::Get());
-  bool GetAndResetHasNewAudioDeviceAdded(JniEnvExt* env = JniEnvExt::Get());
+  bool GetAndResetHasAudioDeviceChanged(JniEnvExt* env = JniEnvExt::Get());
   int GetUnderrunCount(JniEnvExt* env = JniEnvExt::Get());
 
  private:
diff --git a/src/starboard/android/shared/gyp_configuration.py b/src/starboard/android/shared/gyp_configuration.py
index e38efdf..018dbb6 100644
--- a/src/starboard/android/shared/gyp_configuration.py
+++ b/src/starboard/android/shared/gyp_configuration.py
@@ -277,52 +277,6 @@
   # A map of failing or crashing tests per target.
   __FILTERED_TESTS = {  # pylint: disable=invalid-name
       'player_filter_tests': [
-          # All e/ac3 related decoder tests are disabled.  They will be
-          # re-enabled soon once we can filter out audio decoder tests for
-          # passthrough decoders.
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/12',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/26',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/40',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/54',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/68',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/82',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/84',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/86',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/88',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/90',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/92',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/94',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/96',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/98',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/100',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/102',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.SingleInput/104',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/12',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/26',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/40',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/54',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/68',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/82',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/84',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/86',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/88',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/90',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/92',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/94',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/96',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.MultipleInput/98',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
-              'MultipleInput/100',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
-              'MultipleInput/102',
-          'AdaptiveAudioDecoderTests/AdaptiveAudioDecoderTest.' +
-              'MultipleInput/104',
-          'AudioDecoderTests/AudioDecoderTest.SingleInput/12',
-          'AudioDecoderTests/AudioDecoderTest.ResetBeforeInput/12',
-          'AudioDecoderTests/AudioDecoderTest.MultipleInputs/12',
-          'AudioDecoderTests/AudioDecoderTest.LimitedInput/12',
-          'AudioDecoderTests/AudioDecoderTest.ContinuedLimitedInput/12',
-
           # GetMaxNumberOfCachedFrames() on Android is device dependent,
           # and Android doesn't provide an API to get it. So, this function
           # doesn't make sense on Android. But HoldFramesUntilFull tests depend
diff --git a/src/starboard/android/shared/media_is_audio_supported.cc b/src/starboard/android/shared/media_is_audio_supported.cc
index 334c7dd..e7b04de 100644
--- a/src/starboard/android/shared/media_is_audio_supported.cc
+++ b/src/starboard/android/shared/media_is_audio_supported.cc
@@ -46,17 +46,17 @@
     return false;
   }
   MimeType mime_type(content_type);
-  // Allows for disabling the use of the AudioRouting API to detect when audio
-  // peripherals are connected. Enabled by default.
-  // (https://developer.android.com/reference/android/media/AudioRouting)
-  auto enable_audio_routing_parameter_value =
-      mime_type.GetParamStringValue("enableaudiorouting", "");
-  if (!enable_audio_routing_parameter_value.empty() &&
-      enable_audio_routing_parameter_value != "true" &&
-      enable_audio_routing_parameter_value != "false") {
-    SB_LOG(INFO)
-        << "Invalid value for audio mime parameter \"enableaudiorouting\": "
-        << enable_audio_routing_parameter_value << ".";
+  // Allows for disabling the use of the AudioDeviceCallback API to detect when
+  // audio peripherals are connected. Enabled by default.
+  // (https://developer.android.com/reference/android/media/AudioDeviceCallback)
+  auto enable_audio_device_callback_parameter_value =
+      mime_type.GetParamStringValue("enableaudiodevicecallback", "");
+  if (!enable_audio_device_callback_parameter_value.empty() &&
+      enable_audio_device_callback_parameter_value != "true" &&
+      enable_audio_device_callback_parameter_value != "false") {
+    SB_LOG(INFO) << "Invalid value for audio mime parameter "
+                    "\"enableaudiodevicecallback\": "
+                 << enable_audio_device_callback_parameter_value << ".";
     return false;
   }
   // Allows for enabling tunneled playback. Disabled by default.
@@ -78,6 +78,23 @@
     return false;
   }
 
+  auto audio_passthrough_parameter_value =
+      mime_type.GetParamStringValue("audiopassthrough", "");
+  if (!audio_passthrough_parameter_value.empty() &&
+      audio_passthrough_parameter_value != "true" &&
+      audio_passthrough_parameter_value != "false") {
+    SB_LOG(INFO) << "Invalid value for audio mime parameter "
+                    "\"audiopassthrough\": "
+                 << audio_passthrough_parameter_value
+                 << ". Passthrough is disabled.";
+    return false;
+  }
+  if (audio_passthrough_parameter_value == "false" && is_passthrough) {
+    SB_LOG(INFO) << "Passthrough is rejected because audio mime parameter "
+                    "\"audiopassthrough\" == false.";
+    return false;
+  }
+
   JniEnvExt* env = JniEnvExt::Get();
   ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
   const bool must_support_tunnel_mode =
diff --git a/src/starboard/android/shared/player_components_factory.h b/src/starboard/android/shared/player_components_factory.h
index fa64270..b2cbfed 100644
--- a/src/starboard/android/shared/player_components_factory.h
+++ b/src/starboard/android/shared/player_components_factory.h
@@ -64,7 +64,7 @@
 class AudioRendererSinkAndroid : public ::starboard::shared::starboard::player::
                                      filter::AudioRendererSinkImpl {
  public:
-  explicit AudioRendererSinkAndroid(bool enable_audio_routing,
+  explicit AudioRendererSinkAndroid(bool enable_audio_device_callback,
                                     int tunnel_mode_audio_session_id = -1)
       : AudioRendererSinkImpl(
             [=](SbTime start_media_time,
@@ -87,7 +87,8 @@
                   audio_frame_storage_type, frame_buffers,
                   frame_buffers_size_in_frames, update_source_status_func,
                   consume_frames_func, error_func, start_media_time,
-                  tunnel_mode_audio_session_id, enable_audio_routing, context);
+                  tunnel_mode_audio_session_id, enable_audio_device_callback,
+                  context);
             }) {}
 
  private:
@@ -182,9 +183,28 @@
     return (value + alignment - 1) / alignment * alignment;
   }
 
+  static bool IsAudioDeviceCallbackEnabled(
+      const CreationParameters& creation_parameters) {
+    using starboard::shared::starboard::media::MimeType;
+
+    MimeType mime_type(creation_parameters.audio_mime());
+    auto enable_audio_device_callback_parameter_value =
+        mime_type.GetParamStringValue("enableaudiodevicecallback", "");
+    if (enable_audio_device_callback_parameter_value.empty() ||
+        enable_audio_device_callback_parameter_value == "true") {
+      SB_LOG(INFO) << "AudioDeviceCallback is enabled.";
+      return true;
+    }
+    SB_LOG(INFO) << "Mime attribute \"enableaudiodevicecallback\" is set to: "
+                 << enable_audio_device_callback_parameter_value
+                 << ". AudioDeviceCallback is disabled.";
+    return false;
+  }
+
   scoped_ptr<PlayerComponents> CreateComponents(
       const CreationParameters& creation_parameters,
       std::string* error_message) override {
+    using starboard::shared::starboard::media::MimeType;
     SB_DCHECK(error_message);
 
     if (creation_parameters.audio_codec() != kSbMediaAudioCodecAc3 &&
@@ -194,12 +214,21 @@
                                                          error_message);
     }
 
+    MimeType audio_mime_type(creation_parameters.audio_mime());
+    if (audio_mime_type.GetParamStringValue("audiopassthrough", "") ==
+        "false") {
+      SB_LOG(INFO) << "Mime attribute \"audiopassthrough\" is set to: "
+                      "false. Passthrough is disabled.";
+      return scoped_ptr<PlayerComponents>();
+    }
+
     SB_LOG(INFO) << "Creating passthrough components.";
     // TODO: Enable tunnel mode for passthrough
     scoped_ptr<AudioRendererPassthrough> audio_renderer;
     audio_renderer.reset(new AudioRendererPassthrough(
         creation_parameters.audio_sample_info(),
-        GetExtendedDrmSystem(creation_parameters.drm_system())));
+        GetExtendedDrmSystem(creation_parameters.drm_system()),
+        IsAudioDeviceCallbackEnabled(creation_parameters)));
     if (!audio_renderer->is_valid()) {
       return scoped_ptr<PlayerComponents>();
     }
@@ -328,30 +357,20 @@
           creation_parameters.audio_sample_info(),
           GetExtendedDrmSystem(creation_parameters.drm_system()),
           decoder_creator));
-      bool enable_audio_routing = true;
-      MimeType audio_mime_type(creation_parameters.audio_mime());
-      auto enable_audio_routing_parameter_value =
-          audio_mime_type.GetParamStringValue("enableaudiorouting", "");
-      if (enable_audio_routing_parameter_value.empty() ||
-          enable_audio_routing_parameter_value == "true") {
-        SB_LOG(INFO) << "AudioRouting is enabled.";
-      } else {
-        enable_audio_routing = false;
-        SB_LOG(INFO) << "Mime attribute \"enableaudiorouting\" is set to: "
-                     << enable_audio_routing_parameter_value
-                     << ". AudioRouting is disabled.";
-      }
+
+      bool enable_audio_device_callback =
+          IsAudioDeviceCallbackEnabled(creation_parameters);
       if (tunnel_mode_audio_session_id != -1) {
         *audio_renderer_sink = TryToCreateTunnelModeAudioRendererSink(
             tunnel_mode_audio_session_id, creation_parameters,
-            enable_audio_routing);
+            enable_audio_device_callback);
         if (!*audio_renderer_sink) {
           tunnel_mode_audio_session_id = -1;
         }
       }
       if (!*audio_renderer_sink) {
         audio_renderer_sink->reset(
-            new AudioRendererSinkAndroid(enable_audio_routing));
+            new AudioRendererSinkAndroid(enable_audio_device_callback));
       }
     }
 
@@ -523,9 +542,9 @@
   scoped_ptr<AudioRendererSink> TryToCreateTunnelModeAudioRendererSink(
       int tunnel_mode_audio_session_id,
       const CreationParameters& creation_parameters,
-      bool enable_audio_routing) {
+      bool enable_audio_device_callback) {
     scoped_ptr<AudioRendererSink> audio_sink(new AudioRendererSinkAndroid(
-        enable_audio_routing, tunnel_mode_audio_session_id));
+        enable_audio_device_callback, tunnel_mode_audio_session_id));
     // We need to double check if the audio sink can actually be created.
     int max_cached_frames, min_frames_per_append;
     GetAudioRendererParams(creation_parameters, &max_cached_frames,
diff --git a/src/starboard/build/platforms.gni b/src/starboard/build/platforms.gni
index 6a7adcb..b3793c2 100644
--- a/src/starboard/build/platforms.gni
+++ b/src/starboard/build/platforms.gni
@@ -53,4 +53,8 @@
     name = "android-x86"
     path = "starboard/android/x86"
   },
+  {
+    name = "raspi-2"
+    path = "starboard/raspi/2"
+  },
 ]
diff --git a/src/starboard/evergreen/testing/raspi/deploy_cobalt.sh b/src/starboard/evergreen/testing/raspi/deploy_cobalt.sh
index e32b509..6b1b83d 100755
--- a/src/starboard/evergreen/testing/raspi/deploy_cobalt.sh
+++ b/src/starboard/evergreen/testing/raspi/deploy_cobalt.sh
@@ -44,6 +44,9 @@
   echo " Copying loader_app to Cobalt-on-Evergreen directory"
   eval "${SCP} ${OUT}/deploy/loader_app/loader_app pi@${RASPI_ADDR}:/home/pi/coeg/" 1> /dev/null
 
+  echo " Copying crashpad_handler to Cobalt-on-Evergreen directory"
+  eval "${SCP} ${OUT}/deploy/loader_app/crashpad_handler pi@${RASPI_ADDR}:/home/pi/coeg/" 1> /dev/null
+
   echo " Regenerating system image directory"
   eval "${SSH} mkdir -p /home/pi/coeg/content/app/cobalt/lib" 1> /dev/null
 
@@ -53,6 +56,9 @@
   echo " Copying content to system image directory"
   eval "${SCP} -r ${OUT}/deploy/loader_app/content/app/cobalt/content/ pi@${RASPI_ADDR}:/home/pi/coeg/content/app/cobalt/" 1> /dev/null
 
+  echo " Copying fonts to system content directory"
+  eval "${SCP} -r ${OUT}/content/fonts/ pi@${RASPI_ADDR}:/home/pi/coeg/content/" 1> /dev/null
+
   echo " Generating HTML test directory"
   eval "${SSH} mkdir -p /home/pi/coeg/content/app/cobalt/content/web/tests/" 1> /dev/null
 
diff --git a/src/starboard/evergreen/testing/raspi/setup.sh b/src/starboard/evergreen/testing/raspi/setup.sh
index 4135f0a..3292873 100755
--- a/src/starboard/evergreen/testing/raspi/setup.sh
+++ b/src/starboard/evergreen/testing/raspi/setup.sh
@@ -17,7 +17,7 @@
 source $1/../pprint.sh
 source $1/run_command.sh
 
-CACHE_DIR="${HOME}/.cache/cobalt"
+CACHE_DIR="/home/pi/.cache/cobalt"
 CONTENT="/home/pi/coeg/content/app/cobalt/content"
 STORAGE_DIR="/home/pi/.cobalt_storage"
 STORAGE_DIR_TMPFS="${STORAGE_DIR}.tmpfs"
diff --git a/src/starboard/evergreen/testing/tests/crashpad_runs_test.sh b/src/starboard/evergreen/testing/tests/crashpad_runs_test.sh
index f0e1b0a..ebd40ac 100644
--- a/src/starboard/evergreen/testing/tests/crashpad_runs_test.sh
+++ b/src/starboard/evergreen/testing/tests/crashpad_runs_test.sh
@@ -28,7 +28,7 @@
   LOG="${TEST_NAME}.0.log"
   start_cobalt "file:///tests/${TEST_FILE}?channel=tcrash" "${LOG}" LOADER
 
-  if [[ $(ps -C crashpad_handler) -ne 0 ]]; then
+  if [[ $(run_command "ps -C crashpad_handler") -ne 0 ]]; then
     log "error" " Failed to start crashpad_handler"
     return 1
   fi
@@ -54,7 +54,7 @@
     return 1
   fi
 
-  if [[ $(find ${CACHE_DIR}/crashpad_database/completed/ -mmin -3 | ${WC} -l) -eq 0 ]]; then
+  if [[ $(run_command "find ${CACHE_DIR}/crashpad_database/completed/ -mmin -3 | ${WC} -l") -eq 0 ]]; then
     log "error" " Failed upload crash to crash database"
     return 1
   fi
diff --git a/src/starboard/linux/shared/BUILD.gn b/src/starboard/linux/shared/BUILD.gn
index 522b781..9ef03b9 100644
--- a/src/starboard/linux/shared/BUILD.gn
+++ b/src/starboard/linux/shared/BUILD.gn
@@ -398,6 +398,17 @@
   ]
   deps = [ "//third_party/boringssl:crypto" ]
 
+  if (sb_api_version == 12) {
+    sources += [
+      "//starboard/shared/stub/speech_recognizer_cancel.cc",
+      "//starboard/shared/stub/speech_recognizer_create.cc",
+      "//starboard/shared/stub/speech_recognizer_destroy.cc",
+      "//starboard/shared/stub/speech_recognizer_is_supported.cc",
+      "//starboard/shared/stub/speech_recognizer_start.cc",
+      "//starboard/shared/stub/speech_recognizer_stop.cc",
+    ]
+  }
+
   if (is_internal_build) {
     sources += [
       "//starboard/linux/shared/drm_create_system.cc",
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py
index e8a7a9f..4e4a96c 100644
--- a/src/starboard/linux/shared/gyp_configuration.py
+++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -122,7 +122,7 @@
       ],
   }
   # Conditionally disables tests that require ipv6
-  if os.getenv('IPV6_NOT_AVAILABLE', False):
+  if os.getenv('IPV6_AVAILABLE', 1) == '0':
     __FILTERED_TESTS['nplb'] = [
         'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDayDestination/1',
         'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceForDestination/1',
diff --git a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
index a117f3c..4c7457c 100644
--- a/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
+++ b/src/starboard/nplb/media_can_play_mime_and_key_system_test.cc
@@ -175,55 +175,57 @@
 TEST(SbMediaCanPlayMimeAndKeySystem, MinimumSupport) {
   // H.264 High Profile Level 4.2
   SbMediaSupportType result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
-      "framerate=30; bitrate=20000",
+      "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
+      "framerate=30; bitrate=20000000",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 Main Profile Level 4.2
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.4d402a\"; width=1920; height=1080; "
+      "video/mp4; codecs=\"avc1.4d002a\"; width=1920; height=1080; "
       "framerate=30;",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.4d402a\"; width=0; height=0; "
+      "video/mp4; codecs=\"avc1.4d002a\"; width=0; height=0; "
       "framerate=0; bitrate=0",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.4d402a\"; width=-0; height=-0; "
+      "video/mp4; codecs=\"avc1.4d002a\"; width=-0; height=-0; "
       "framerate=-0; bitrate=-0",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 Main Profile Level 2.1
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.4d4015\"; width=432; height=240; "
+      "video/mp4; codecs=\"avc1.4d0015\"; width=432; height=240; "
       "framerate=15;",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // AV1 Main Profile 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"av01.0.05M.08\"; width=1920; height=1080; "
-      "framerate=30; bitrate=20000",
+      "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+      "framerate=30; bitrate=20000000",
       "");
 
   // VP9 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=60", "");
+      "video/webm; codecs=\"vp9\"; width=1920; height=1080; framerate=60; "
+      "bitrate=20000000",
+      "");
 
   // AAC-LC
   result = SbMediaCanPlayMimeAndKeySystem(
-      "audio/mp4; codecs=\"mp4a.40.2\"; channels=2; bitrate=256;", "");
+      "audio/mp4; codecs=\"mp4a.40.2\"; channels=2; bitrate=256000;", "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // HE-AAC
   result = SbMediaCanPlayMimeAndKeySystem(
-      "audio/mp4; codecs=\"mp4a.40.5\"; channels=2; bitrate=48;", "");
+      "audio/mp4; codecs=\"mp4a.40.5\"; channels=2; bitrate=48000;", "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 }
 
@@ -286,6 +288,7 @@
   }
 }
 
+// TODO: Create an abstraction to shorten the length of this test.
 TEST(SbMediaCanPlayMimeAndKeySystem, PrintMaximumSupport) {
   // AVC
   std::string avc_resolution = "Unsupported";
@@ -298,14 +301,14 @@
     avc_resolution = "1080p";
     // 2K
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"avc1.64402a\"; width=2560; height=1440; "
+        "video/mp4; codecs=\"avc1.64002a\"; width=2560; height=1440; "
         "framerate=30",
         "");
     if (result == kSbMediaSupportTypeProbably) {
       avc_resolution = "2K";
       // 4K
       result = SbMediaCanPlayMimeAndKeySystem(
-          "video/mp4; codecs=\"avc1.64402a\"; width=3840; height=2160; "
+          "video/mp4; codecs=\"avc1.64002a\"; width=3840; height=2160; "
           "framerate=30",
           "");
       if (result == kSbMediaSupportTypeProbably) {
@@ -392,7 +395,7 @@
   // 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
       "video/webm; codecs=\"vp09.02.51.10.01.09.16.09.00\"; width=1920; "
-      "height=1080",
+      "height=1080; framerate=30",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     vp9_hdr_resolution = "1080p";
@@ -418,21 +421,21 @@
   std::string av1_resolution = "Unsupported";
   // 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
+      "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; "
       "height=1080; framerate=30",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     av1_resolution = "1080p";
     // 2K
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
+        "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; "
         "height=1440; framerate=30",
         "");
     if (result == kSbMediaSupportTypeProbably) {
       av1_resolution = "2K";
       // 4K
       result = SbMediaCanPlayMimeAndKeySystem(
-          "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
+          "video/mp4; codecs=\"av01.0.12M.08\"; width=3840; "
           "height=2160; framerate=30",
           "");
       if (result == kSbMediaSupportTypeProbably) {
@@ -444,22 +447,22 @@
   std::string av1_hfr_resolution = "Unsupported";
   // 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"av01.0.08M.08\"; width=1920; "
-      "height=1080; framerate=60",
+      "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+      "framerate=60",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     av1_hfr_resolution = "1080p";
     // 2K
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.08M.08\"; width=2560; "
-        "height=1440; framerate=60",
+        "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; height=1440; "
+        "framerate=60",
         "");
     if (result == kSbMediaSupportTypeProbably) {
       av1_hfr_resolution = "2K";
       // 4K
       result = SbMediaCanPlayMimeAndKeySystem(
-          "video/mp4; codecs=\"av01.0.08M.08\"; width=3840; "
-          "height=2160; framerate=60",
+          "video/mp4; codecs=\"av01.0.13M.08\"; width=3840; height=2160; "
+          "framerate=60",
           "");
       if (result == kSbMediaSupportTypeProbably) {
         av1_hfr_resolution = "4K";
@@ -472,21 +475,21 @@
   // 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
       "video/mp4; codecs=\"av01.0.09M.10.0.110.09.16.09.0\"; width=1920; "
-      "height=1080; framerate=30",
+      "height=1080",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     av1_hdr_resolution = "1080p";
     // 2K
     result = SbMediaCanPlayMimeAndKeySystem(
         "video/mp4; codecs=\"av01.0.12M.10.0.110.09.16.09.0\"; width=2560; "
-        "height=1440; framerate=30",
+        "height=1440",
         "");
     if (result == kSbMediaSupportTypeProbably) {
       av1_hdr_resolution = "2K";
       // 4K
       result = SbMediaCanPlayMimeAndKeySystem(
           "video/mp4; codecs=\"av01.0.13M.10.0.110.09.16.09.0\"; width=3840; "
-          "height=2160; framerate=30",
+          "height=2160",
           "");
       if (result == kSbMediaSupportTypeProbably) {
         av1_hdr_resolution = "4K";
@@ -514,7 +517,7 @@
   std::string opus_support = "Unsupported";
   result = SbMediaCanPlayMimeAndKeySystem(
       "audio/webm; codecs=\"opus\"; "
-      "channels=2; bitrate=576;",
+      "channels=2; bitrate=128000;",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     opus_support = "Supported";
@@ -524,7 +527,7 @@
   std::string opus51_support = "Unsupported";
   result = SbMediaCanPlayMimeAndKeySystem(
       "audio/webm; codecs=\"opus\"; "
-      "channels=6; bitrate=576;",
+      "channels=6; bitrate=576000;",
       "");
   if (result == kSbMediaSupportTypeProbably) {
     opus51_support = "Supported";
@@ -533,7 +536,7 @@
   // AC-3
   std::string ac3_support = "Unsupported";
   result = SbMediaCanPlayMimeAndKeySystem(
-      "audio/mp4; codecs=\"ac-3\"; channels=2", "");
+      "audio/mp4; codecs=\"ac-3\"; channels=6; bitrate=512000", "");
   if (result == kSbMediaSupportTypeProbably) {
     ac3_support = "Supported";
   }
@@ -541,7 +544,7 @@
   // E-AC-3
   std::string eac3_support = "Unsupported";
   result = SbMediaCanPlayMimeAndKeySystem(
-      "audio/mp4; codecs=\"ec-3\"; channels=2", "");
+      "audio/mp4; codecs=\"ec-3\"; channels=6; bitrate=512000", "");
   if (result == kSbMediaSupportTypeProbably) {
     eac3_support = "Supported";
   }
@@ -561,59 +564,60 @@
                << "\n\tAC-3: " << ac3_support << "\n\tE-AC-3: " << eac3_support;
 }
 
+// TODO: Create an abstraction to shorten the length of this test.
 TEST(SbMediaCanPlayMimeAndKeySystem, ValidateQueriesUnderPeakCapability) {
   // H.264 High Profile Level 4.2 1080p 25 fps
   SbMediaSupportType result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
       "framerate=25",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 1080p 24 fps
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=1080; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=1080; "
       "framerate=24",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 1920x818
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=1920; height=818; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=1920; height=818; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 720p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=1280; height=720; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=1280; height=720; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 480p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=640; height=480; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=640; height=480; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 360p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=480; height=360; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=480; height=360; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 240p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=352; height=240; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=352; height=240; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
   // H.264 High Profile Level 4.2 144p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"avc1.64402a\"; width=256; height=144; "
+      "video/mp4; codecs=\"avc1.64002a\"; width=256; height=144; "
       "framerate=30",
       "");
   ASSERT_EQ(result, kSbMediaSupportTypeProbably);
@@ -635,78 +639,78 @@
 
   // AV1 Main Profile 4K
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"av01.0.13M.10.0.110.09.16.09.0\"; width=3840; "
-      "height=2160; framerate=30",
+      "video/mp4; codecs=\"av01.0.12M.08\"; width=3840; height=2160; "
+      "framerate=30",
       "");
 
   if (result == kSbMediaSupportTypeProbably) {
     // AV1 Main Profile 1440p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.12M.10.0.110.09.16.09.0\"; width=2560; "
-        "height=1440; framerate=30",
+        "video/mp4; codecs=\"av01.0.12M.08\"; width=2560; height=1440; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
   }
   // AV1 Main Profile 1080p
   result = SbMediaCanPlayMimeAndKeySystem(
-      "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
-      "height=1080; framerate=30",
+      "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+      "framerate=30",
       "");
 
   if (result == kSbMediaSupportTypeProbably) {
     // AV1 Main Profile 1080p 25 fps
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
-        "height=1080; framerate=25",
+        "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+        "framerate=25",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 1080p 24 fps
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
-        "height=1080; framerate=24",
+        "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=1080; "
+        "framerate=24",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 1920x818
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.09M.08.0.110.09.16.09.0\"; width=1920; "
-        "height=818; framerate=30",
+        "video/mp4; codecs=\"av01.0.09M.08\"; width=1920; height=818; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 720p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.08M.10.0.110.09.16.09.0\"; width=1280; "
-        "height=720; framerate=30",
+        "video/mp4; codecs=\"av01.0.05M.08\"; width=1280; height=720; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 480p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.04M.10.0.110.09.16.09.0\"; width=854; "
-        "height=480; framerate=30",
+        "video/mp4; codecs=\"av01.0.04M.08\"; width=854; height=480; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 360p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.01M.10.0.110.09.16.09.0\"; width=640; "
-        "height=360; framerate=30",
+        "video/mp4; codecs=\"av01.0.01M.08\"; width=640; height=360; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 240p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.00M.10.0.110.09.16.09.0\"; width=426; "
-        "height=240; framerate=30",
+        "video/mp4; codecs=\"av01.0.00M.08\"; width=426; height=240; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
 
     // AV1 Main Profile 144p
     result = SbMediaCanPlayMimeAndKeySystem(
-        "video/mp4; codecs=\"av01.0.00M.10.0.110.09.16.09.0\"; width=256; "
-        "height=144; framerate=30",
+        "video/mp4; codecs=\"av01.0.00M.08\"; width=256; height=144; "
+        "framerate=30",
         "");
     ASSERT_EQ(result, kSbMediaSupportTypeProbably);
   }
diff --git a/src/starboard/raspi/2/BUILD.gn b/src/starboard/raspi/2/BUILD.gn
new file mode 100644
index 0000000..3cf94e9
--- /dev/null
+++ b/src/starboard/raspi/2/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+static_library("starboard_platform") {
+  check_includes = false
+  configs += [ "//starboard/build/config:starboard_implementation" ]
+
+  public_deps = [ "//starboard/raspi/shared:starboard_platform" ]
+}
diff --git a/src/starboard/raspi/2/platform_configuration/BUILD.gn b/src/starboard/raspi/2/platform_configuration/BUILD.gn
new file mode 100644
index 0000000..ef03b60
--- /dev/null
+++ b/src/starboard/raspi/2/platform_configuration/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2021 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.
+
+config("platform_configuration") {
+  configs = [
+    "//starboard/build/config/sabi",
+    "//starboard/raspi/shared/platform_configuration",
+  ]
+  cflags = [
+    "-march=armv7-a",
+    "-mfpu=neon-vfpv4",
+    "-mfloat-abi=hard",
+    "-mcpu=cortex-a8",
+    "-mtune=cortex-a8",
+  ]
+}
diff --git a/src/starboard/raspi/2/platform_configuration/configuration.gni b/src/starboard/raspi/2/platform_configuration/configuration.gni
new file mode 100644
index 0000000..77ec5a9
--- /dev/null
+++ b/src/starboard/raspi/2/platform_configuration/configuration.gni
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+import("//starboard/raspi/shared/platform_configuration/configuration.gni")
+
+arm_float_abi = "hard"
+
+sb_evergreen_compatible_use_libunwind = true
+sb_is_evergreen_compatible = true
diff --git a/src/starboard/raspi/2/toolchain/BUILD.gn b/src/starboard/raspi/2/toolchain/BUILD.gn
new file mode 100644
index 0000000..57a35ca
--- /dev/null
+++ b/src/starboard/raspi/2/toolchain/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2021 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.
+
+import("//build/toolchain/gcc_toolchain.gni")
+
+_home_dir = getenv("HOME")
+_clang_base_path = "$_home_dir/starboard-toolchains/x86_64-linux-gnu-clang-chromium-365097-f7e52fbd-8"
+raspi_toolchain_path = "$_home_dir/raspi_tools/tools/arm-bcm2708/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin"
+
+clang_toolchain("host") {
+  clang_base_path = _clang_base_path
+}
+
+gcc_toolchain("target") {
+  cc = "$raspi_toolchain_path/arm-linux-gnueabihf-gcc"
+  cxx = "$raspi_toolchain_path/arm-linux-gnueabihf-g++"
+  ld = cxx
+
+  # We use whatever 'ar' resolves to in gyp.
+  ar = "ar"
+  strip = "$raspi_toolchain_path/arm-linux-gnueabihf-strip"
+
+  toolchain_args = {
+    is_clang = false
+  }
+}
diff --git a/src/starboard/raspi/shared/BUILD.gn b/src/starboard/raspi/shared/BUILD.gn
new file mode 100644
index 0000000..37c97e7
--- /dev/null
+++ b/src/starboard/raspi/shared/BUILD.gn
@@ -0,0 +1,412 @@
+# Copyright 2021 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.
+import("//starboard/shared/starboard/player/buildfiles.gni")
+
+group("starboard_platform") {
+  public_deps = [ ":starboard_platform_sources" ]
+}
+
+static_library("starboard_platform_sources") {
+  sources = [
+    "//starboard/linux/shared/atomic_public.h",
+    "//starboard/linux/shared/configuration_constants.cc",
+    "//starboard/linux/shared/configuration_public.h",
+    "//starboard/linux/shared/netlink.cc",
+    "//starboard/linux/shared/netlink.h",
+    "//starboard/linux/shared/routes.cc",
+    "//starboard/linux/shared/routes.h",
+    "//starboard/linux/shared/system_get_connection_type.cc",
+    "//starboard/linux/shared/system_get_path.cc",
+    "//starboard/linux/shared/system_has_capability.cc",
+    "//starboard/raspi/shared/application_dispmanx.cc",
+    "//starboard/raspi/shared/audio_sink_type_dispatcher.cc",
+    "//starboard/raspi/shared/configuration.cc",
+    "//starboard/raspi/shared/configuration.h",
+    "//starboard/raspi/shared/dispmanx_util.cc",
+    "//starboard/raspi/shared/dispmanx_util.h",
+    "//starboard/raspi/shared/graphics.cc",
+    "//starboard/raspi/shared/graphics.h",
+    "//starboard/raspi/shared/main.cc",
+    "//starboard/raspi/shared/media_is_video_supported.cc",
+    "//starboard/raspi/shared/open_max/decode_target_create.cc",
+    "//starboard/raspi/shared/open_max/decode_target_create.h",
+    "//starboard/raspi/shared/open_max/decode_target_get_info.cc",
+    "//starboard/raspi/shared/open_max/decode_target_internal.h",
+    "//starboard/raspi/shared/open_max/decode_target_release.cc",
+    "//starboard/raspi/shared/open_max/dispmanx_resource_pool.cc",
+    "//starboard/raspi/shared/open_max/dispmanx_resource_pool.h",
+    "//starboard/raspi/shared/open_max/image_decode.cc",
+    "//starboard/raspi/shared/open_max/image_is_decode_supported.cc",
+    "//starboard/raspi/shared/open_max/open_max_component.cc",
+    "//starboard/raspi/shared/open_max/open_max_component.h",
+    "//starboard/raspi/shared/open_max/open_max_component_base.cc",
+    "//starboard/raspi/shared/open_max/open_max_component_base.h",
+    "//starboard/raspi/shared/open_max/open_max_egl_render_component.cc",
+    "//starboard/raspi/shared/open_max/open_max_egl_render_component.h",
+    "//starboard/raspi/shared/open_max/open_max_image_decode_component.cc",
+    "//starboard/raspi/shared/open_max/open_max_image_decode_component.h",
+    "//starboard/raspi/shared/open_max/open_max_video_decode_component.cc",
+    "//starboard/raspi/shared/open_max/open_max_video_decode_component.h",
+    "//starboard/raspi/shared/open_max/video_decoder.cc",
+    "//starboard/raspi/shared/open_max/video_decoder.h",
+    "//starboard/raspi/shared/player_components_factory.cc",
+    "//starboard/raspi/shared/system_get_device_type.cc",
+    "//starboard/raspi/shared/system_get_extensions.cc",
+    "//starboard/raspi/shared/system_get_property.cc",
+    "//starboard/raspi/shared/system_gles2.cc",
+    "//starboard/raspi/shared/thread_create_priority.cc",
+    "//starboard/raspi/shared/video_renderer_sink_impl.cc",
+    "//starboard/raspi/shared/video_renderer_sink_impl.h",
+    "//starboard/raspi/shared/window_create.cc",
+    "//starboard/raspi/shared/window_destroy.cc",
+    "//starboard/raspi/shared/window_get_platform_handle.cc",
+    "//starboard/raspi/shared/window_get_size.cc",
+    "//starboard/raspi/shared/window_internal.cc",
+    "//starboard/shared/alsa/alsa_audio_sink_type.cc",
+    "//starboard/shared/alsa/alsa_audio_sink_type.h",
+    "//starboard/shared/alsa/alsa_util.cc",
+    "//starboard/shared/alsa/alsa_util.h",
+    "//starboard/shared/dlmalloc/memory_map.cc",
+    "//starboard/shared/dlmalloc/memory_protect.cc",
+    "//starboard/shared/dlmalloc/memory_unmap.cc",
+    "//starboard/shared/egl/system_egl.cc",
+    "//starboard/shared/gcc/atomic_gcc_public.h",
+    "//starboard/shared/iso/character_is_alphanumeric.cc",
+    "//starboard/shared/iso/character_is_digit.cc",
+    "//starboard/shared/iso/character_is_hex_digit.cc",
+    "//starboard/shared/iso/character_is_space.cc",
+    "//starboard/shared/iso/character_is_upper.cc",
+    "//starboard/shared/iso/character_to_lower.cc",
+    "//starboard/shared/iso/character_to_upper.cc",
+    "//starboard/shared/iso/directory_close.cc",
+    "//starboard/shared/iso/directory_get_next.cc",
+    "//starboard/shared/iso/directory_open.cc",
+    "//starboard/shared/iso/double_absolute.cc",
+    "//starboard/shared/iso/double_exponent.cc",
+    "//starboard/shared/iso/double_floor.cc",
+    "//starboard/shared/iso/double_is_finite.cc",
+    "//starboard/shared/iso/double_is_nan.cc",
+    "//starboard/shared/iso/memory_allocate_unchecked.cc",
+    "//starboard/shared/iso/memory_compare.cc",
+    "//starboard/shared/iso/memory_copy.cc",
+    "//starboard/shared/iso/memory_find_byte.cc",
+    "//starboard/shared/iso/memory_free.cc",
+    "//starboard/shared/iso/memory_move.cc",
+    "//starboard/shared/iso/memory_reallocate_unchecked.cc",
+    "//starboard/shared/iso/memory_set.cc",
+    "//starboard/shared/iso/string_compare.cc",
+    "//starboard/shared/iso/string_compare_all.cc",
+    "//starboard/shared/iso/string_find_character.cc",
+    "//starboard/shared/iso/string_find_last_character.cc",
+    "//starboard/shared/iso/string_find_string.cc",
+    "//starboard/shared/iso/string_get_length.cc",
+    "//starboard/shared/iso/string_get_length_wide.cc",
+    "//starboard/shared/iso/string_parse_double.cc",
+    "//starboard/shared/iso/string_parse_signed_integer.cc",
+    "//starboard/shared/iso/string_parse_uint64.cc",
+    "//starboard/shared/iso/string_parse_unsigned_integer.cc",
+    "//starboard/shared/iso/string_scan.cc",
+    "//starboard/shared/iso/system_binary_search.cc",
+    "//starboard/shared/iso/system_sort.cc",
+    "//starboard/shared/libevent/socket_waiter_add.cc",
+    "//starboard/shared/libevent/socket_waiter_create.cc",
+    "//starboard/shared/libevent/socket_waiter_destroy.cc",
+    "//starboard/shared/libevent/socket_waiter_internal.cc",
+    "//starboard/shared/libevent/socket_waiter_remove.cc",
+    "//starboard/shared/libevent/socket_waiter_wait.cc",
+    "//starboard/shared/libevent/socket_waiter_wait_timed.cc",
+    "//starboard/shared/libevent/socket_waiter_wake_up.cc",
+    "//starboard/shared/linux/byte_swap.cc",
+    "//starboard/shared/linux/cpu_features_get.cc",
+    "//starboard/shared/linux/dev_input/dev_input.cc",
+    "//starboard/shared/linux/get_home_directory.cc",
+    "//starboard/shared/linux/memory_get_stack_bounds.cc",
+    "//starboard/shared/linux/page_internal.cc",
+    "//starboard/shared/linux/socket_get_interface_address.cc",
+    "//starboard/shared/linux/system_get_random_data.cc",
+    "//starboard/shared/linux/system_get_stack.cc",
+    "//starboard/shared/linux/system_get_total_cpu_memory.cc",
+    "//starboard/shared/linux/system_get_used_cpu_memory.cc",
+    "//starboard/shared/linux/system_is_debugger_attached.cc",
+    "//starboard/shared/linux/system_symbolize.cc",
+    "//starboard/shared/linux/thread_get_id.cc",
+    "//starboard/shared/linux/thread_get_name.cc",
+    "//starboard/shared/linux/thread_set_name.cc",
+    "//starboard/shared/nouser/user_get_current.cc",
+    "//starboard/shared/nouser/user_get_property.cc",
+    "//starboard/shared/nouser/user_get_signed_in.cc",
+    "//starboard/shared/nouser/user_internal.cc",
+    "//starboard/shared/opus/opus_audio_decoder.cc",
+    "//starboard/shared/opus/opus_audio_decoder.h",
+    "//starboard/shared/posix/directory_create.cc",
+    "//starboard/shared/posix/file_atomic_replace.cc",
+    "//starboard/shared/posix/file_can_open.cc",
+    "//starboard/shared/posix/file_close.cc",
+    "//starboard/shared/posix/file_delete.cc",
+    "//starboard/shared/posix/file_exists.cc",
+    "//starboard/shared/posix/file_flush.cc",
+    "//starboard/shared/posix/file_get_info.cc",
+    "//starboard/shared/posix/file_get_path_info.cc",
+    "//starboard/shared/posix/file_open.cc",
+    "//starboard/shared/posix/file_read.cc",
+    "//starboard/shared/posix/file_seek.cc",
+    "//starboard/shared/posix/file_truncate.cc",
+    "//starboard/shared/posix/file_write.cc",
+    "//starboard/shared/posix/log.cc",
+    "//starboard/shared/posix/log_flush.cc",
+    "//starboard/shared/posix/log_format.cc",
+    "//starboard/shared/posix/log_is_tty.cc",
+    "//starboard/shared/posix/log_raw.cc",
+    "//starboard/shared/posix/memory_allocate_aligned_unchecked.cc",
+    "//starboard/shared/posix/memory_flush.cc",
+    "//starboard/shared/posix/memory_free_aligned.cc",
+    "//starboard/shared/posix/set_non_blocking_internal.cc",
+    "//starboard/shared/posix/socket_accept.cc",
+    "//starboard/shared/posix/socket_bind.cc",
+    "//starboard/shared/posix/socket_clear_last_error.cc",
+    "//starboard/shared/posix/socket_connect.cc",
+    "//starboard/shared/posix/socket_create.cc",
+    "//starboard/shared/posix/socket_destroy.cc",
+    "//starboard/shared/posix/socket_free_resolution.cc",
+    "//starboard/shared/posix/socket_get_last_error.cc",
+    "//starboard/shared/posix/socket_get_local_address.cc",
+    "//starboard/shared/posix/socket_internal.cc",
+    "//starboard/shared/posix/socket_is_connected.cc",
+    "//starboard/shared/posix/socket_is_connected_and_idle.cc",
+    "//starboard/shared/posix/socket_is_ipv6_supported.cc",
+    "//starboard/shared/posix/socket_join_multicast_group.cc",
+    "//starboard/shared/posix/socket_listen.cc",
+    "//starboard/shared/posix/socket_receive_from.cc",
+    "//starboard/shared/posix/socket_resolve.cc",
+    "//starboard/shared/posix/socket_send_to.cc",
+    "//starboard/shared/posix/socket_set_broadcast.cc",
+    "//starboard/shared/posix/socket_set_receive_buffer_size.cc",
+    "//starboard/shared/posix/socket_set_reuse_address.cc",
+    "//starboard/shared/posix/socket_set_send_buffer_size.cc",
+    "//starboard/shared/posix/socket_set_tcp_keep_alive.cc",
+    "//starboard/shared/posix/socket_set_tcp_no_delay.cc",
+    "//starboard/shared/posix/socket_set_tcp_window_scaling.cc",
+    "//starboard/shared/posix/storage_write_record.cc",
+    "//starboard/shared/posix/string_compare_no_case.cc",
+    "//starboard/shared/posix/string_compare_no_case_n.cc",
+    "//starboard/shared/posix/string_compare_wide.cc",
+    "//starboard/shared/posix/string_format.cc",
+    "//starboard/shared/posix/string_format_wide.cc",
+    "//starboard/shared/posix/system_break_into_debugger.cc",
+    "//starboard/shared/posix/system_clear_last_error.cc",
+    "//starboard/shared/posix/system_get_error_string.cc",
+    "//starboard/shared/posix/system_get_last_error.cc",
+    "//starboard/shared/posix/system_get_locale_id.cc",
+    "//starboard/shared/posix/system_get_number_of_processors.cc",
+    "//starboard/shared/posix/thread_sleep.cc",
+    "//starboard/shared/posix/time_get_monotonic_now.cc",
+    "//starboard/shared/posix/time_get_monotonic_thread_now.cc",
+    "//starboard/shared/posix/time_get_now.cc",
+    "//starboard/shared/posix/time_is_time_thread_now_supported.cc",
+    "//starboard/shared/posix/time_zone_get_current.cc",
+    "//starboard/shared/posix/time_zone_get_name.cc",
+    "//starboard/shared/pthread/condition_variable_broadcast.cc",
+    "//starboard/shared/pthread/condition_variable_create.cc",
+    "//starboard/shared/pthread/condition_variable_destroy.cc",
+    "//starboard/shared/pthread/condition_variable_signal.cc",
+    "//starboard/shared/pthread/condition_variable_wait.cc",
+    "//starboard/shared/pthread/condition_variable_wait_timed.cc",
+    "//starboard/shared/pthread/mutex_acquire.cc",
+    "//starboard/shared/pthread/mutex_acquire_try.cc",
+    "//starboard/shared/pthread/mutex_create.cc",
+    "//starboard/shared/pthread/mutex_destroy.cc",
+    "//starboard/shared/pthread/mutex_release.cc",
+    "//starboard/shared/pthread/once.cc",
+    "//starboard/shared/pthread/thread_context_get_pointer.cc",
+    "//starboard/shared/pthread/thread_context_internal.cc",
+    "//starboard/shared/pthread/thread_context_internal.h",
+    "//starboard/shared/pthread/thread_create.cc",
+    "//starboard/shared/pthread/thread_create_local_key.cc",
+    "//starboard/shared/pthread/thread_create_priority.h",
+    "//starboard/shared/pthread/thread_destroy_local_key.cc",
+    "//starboard/shared/pthread/thread_detach.cc",
+    "//starboard/shared/pthread/thread_get_current.cc",
+    "//starboard/shared/pthread/thread_get_local_value.cc",
+    "//starboard/shared/pthread/thread_is_equal.cc",
+    "//starboard/shared/pthread/thread_join.cc",
+    "//starboard/shared/pthread/thread_sampler_create.cc",
+    "//starboard/shared/pthread/thread_sampler_destroy.cc",
+    "//starboard/shared/pthread/thread_sampler_freeze.cc",
+    "//starboard/shared/pthread/thread_sampler_internal.cc",
+    "//starboard/shared/pthread/thread_sampler_internal.h",
+    "//starboard/shared/pthread/thread_sampler_is_supported.cc",
+    "//starboard/shared/pthread/thread_sampler_thaw.cc",
+    "//starboard/shared/pthread/thread_set_local_value.cc",
+    "//starboard/shared/pthread/thread_yield.cc",
+    "//starboard/shared/signal/crash_signals.cc",
+    "//starboard/shared/signal/crash_signals.h",
+    "//starboard/shared/signal/suspend_signals.cc",
+    "//starboard/shared/signal/suspend_signals.h",
+    "//starboard/shared/signal/system_request_conceal.cc",
+    "//starboard/shared/signal/system_request_freeze.cc",
+    "//starboard/shared/signal/system_request_suspend.cc",
+    "//starboard/shared/starboard/application.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_create.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_destroy.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_get_max_channels_5_1.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_get_min_buffer_size_in_frames.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_get_nearest_supported_sample_frequency.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_internal.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_internal.h",
+    "//starboard/shared/starboard/audio_sink/audio_sink_is_audio_frame_storage_type_supported_interleaved_only.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_is_audio_sample_type_supported_float32_only.cc",
+    "//starboard/shared/starboard/audio_sink/audio_sink_is_valid.cc",
+    "//starboard/shared/starboard/audio_sink/stub_audio_sink_type.cc",
+    "//starboard/shared/starboard/audio_sink/stub_audio_sink_type.h",
+    "//starboard/shared/starboard/command_line.cc",
+    "//starboard/shared/starboard/command_line.h",
+    "//starboard/shared/starboard/crash_handler.cc",
+    "//starboard/shared/starboard/crash_handler.h",
+    "//starboard/shared/starboard/directory_can_open.cc",
+    "//starboard/shared/starboard/event_cancel.cc",
+    "//starboard/shared/starboard/event_schedule.cc",
+    "//starboard/shared/starboard/file_atomic_replace_write_file.cc",
+    "//starboard/shared/starboard/file_atomic_replace_write_file.h",
+    "//starboard/shared/starboard/file_mode_string_to_flags.cc",
+    "//starboard/shared/starboard/file_storage/storage_close_record.cc",
+    "//starboard/shared/starboard/file_storage/storage_delete_record.cc",
+    "//starboard/shared/starboard/file_storage/storage_get_record_size.cc",
+    "//starboard/shared/starboard/file_storage/storage_open_record.cc",
+    "//starboard/shared/starboard/file_storage/storage_read_record.cc",
+    "//starboard/shared/starboard/log_mutex.cc",
+    "//starboard/shared/starboard/log_mutex.h",
+    "//starboard/shared/starboard/log_raw_dump_stack.cc",
+    "//starboard/shared/starboard/log_raw_format.cc",
+    "//starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc",
+    "//starboard/shared/starboard/media/media_get_audio_buffer_budget.cc",
+    "//starboard/shared/starboard/media/media_get_audio_configuration_5_1.cc",
+    "//starboard/shared/starboard/media/media_get_audio_output_count_single_audio_output.cc",
+    "//starboard/shared/starboard/media/media_get_buffer_alignment.cc",
+    "//starboard/shared/starboard/media/media_get_buffer_allocation_unit.cc",
+    "//starboard/shared/starboard/media/media_get_buffer_garbage_collection_duration_threshold.cc",
+    "//starboard/shared/starboard/media/media_get_buffer_padding.cc",
+    "//starboard/shared/starboard/media/media_get_buffer_storage_type.cc",
+    "//starboard/shared/starboard/media/media_get_initial_buffer_capacity.cc",
+    "//starboard/shared/starboard/media/media_get_max_buffer_capacity.cc",
+    "//starboard/shared/starboard/media/media_get_progressive_buffer_budget.cc",
+    "//starboard/shared/starboard/media/media_get_video_buffer_budget.cc",
+    "//starboard/shared/starboard/media/media_is_audio_supported_aac_and_opus.cc",
+    "//starboard/shared/starboard/media/media_is_buffer_pool_allocate_on_demand.cc",
+    "//starboard/shared/starboard/media/media_is_buffer_using_memory_pool.cc",
+    "//starboard/shared/starboard/media/media_is_transfer_characteristics_supported.cc",
+    "//starboard/shared/starboard/media/mime_type.cc",
+    "//starboard/shared/starboard/media/mime_type.h",
+    "//starboard/shared/starboard/memory.cc",
+    "//starboard/shared/starboard/new.cc",
+    "//starboard/shared/starboard/queue_application.cc",
+    "//starboard/shared/starboard/string_concat.cc",
+    "//starboard/shared/starboard/string_concat_wide.cc",
+    "//starboard/shared/starboard/string_copy.cc",
+    "//starboard/shared/starboard/string_copy_wide.cc",
+    "//starboard/shared/starboard/string_duplicate.cc",
+    "//starboard/shared/starboard/system_get_random_uint64.cc",
+    "//starboard/shared/starboard/system_request_blur.cc",
+    "//starboard/shared/starboard/system_request_focus.cc",
+    "//starboard/shared/starboard/system_request_pause.cc",
+    "//starboard/shared/starboard/system_request_reveal.cc",
+    "//starboard/shared/starboard/system_request_stop.cc",
+    "//starboard/shared/starboard/system_request_unpause.cc",
+    "//starboard/shared/starboard/system_supports_resume.cc",
+    "//starboard/shared/starboard/window_set_default_options.cc",
+    "//starboard/shared/stub/accessibility_get_caption_settings.cc",
+    "//starboard/shared/stub/accessibility_get_display_settings.cc",
+    "//starboard/shared/stub/accessibility_get_text_to_speech_settings.cc",
+    "//starboard/shared/stub/accessibility_set_captions_enabled.cc",
+    "//starboard/shared/stub/cryptography_create_transformer.cc",
+    "//starboard/shared/stub/cryptography_destroy_transformer.cc",
+    "//starboard/shared/stub/cryptography_get_tag.cc",
+    "//starboard/shared/stub/cryptography_set_authenticated_data.cc",
+    "//starboard/shared/stub/cryptography_set_initialization_vector.cc",
+    "//starboard/shared/stub/cryptography_transform.cc",
+    "//starboard/shared/stub/drm_close_session.cc",
+    "//starboard/shared/stub/drm_create_system.cc",
+    "//starboard/shared/stub/drm_destroy_system.cc",
+    "//starboard/shared/stub/drm_generate_session_update_request.cc",
+    "//starboard/shared/stub/drm_get_metrics.cc",
+    "//starboard/shared/stub/drm_is_server_certificate_updatable.cc",
+    "//starboard/shared/stub/drm_update_server_certificate.cc",
+    "//starboard/shared/stub/drm_update_session.cc",
+    "//starboard/shared/stub/media_is_supported.cc",
+    "//starboard/shared/stub/media_set_audio_write_duration.cc",
+    "//starboard/shared/stub/microphone_close.cc",
+    "//starboard/shared/stub/microphone_create.cc",
+    "//starboard/shared/stub/microphone_destroy.cc",
+    "//starboard/shared/stub/microphone_get_available.cc",
+    "//starboard/shared/stub/microphone_is_sample_rate_supported.cc",
+    "//starboard/shared/stub/microphone_open.cc",
+    "//starboard/shared/stub/microphone_read.cc",
+    "//starboard/shared/stub/speech_synthesis_cancel.cc",
+    "//starboard/shared/stub/speech_synthesis_is_supported.cc",
+    "//starboard/shared/stub/speech_synthesis_speak.cc",
+    "//starboard/shared/stub/system_get_total_gpu_memory.cc",
+    "//starboard/shared/stub/system_get_used_gpu_memory.cc",
+    "//starboard/shared/stub/system_hide_splash_screen.cc",
+    "//starboard/shared/stub/system_network_is_disconnected.cc",
+    "//starboard/shared/stub/system_raise_platform_error.cc",
+    "//starboard/shared/stub/system_sign_with_certification_secret_key.cc",
+    "//starboard/shared/stub/ui_nav_get_interface.cc",
+    "//starboard/shared/stub/window_blur_on_screen_keyboard.cc",
+    "//starboard/shared/stub/window_focus_on_screen_keyboard.cc",
+    "//starboard/shared/stub/window_get_diagonal_size_in_inches.cc",
+    "//starboard/shared/stub/window_get_on_screen_keyboard_bounding_rect.cc",
+    "//starboard/shared/stub/window_hide_on_screen_keyboard.cc",
+    "//starboard/shared/stub/window_is_on_screen_keyboard_shown.cc",
+    "//starboard/shared/stub/window_on_screen_keyboard_is_supported.cc",
+    "//starboard/shared/stub/window_on_screen_keyboard_suggestions_supported.cc",
+    "//starboard/shared/stub/window_set_on_screen_keyboard_keep_focus.cc",
+    "//starboard/shared/stub/window_show_on_screen_keyboard.cc",
+    "//starboard/shared/stub/window_update_on_screen_keyboard_suggestions.cc",
+  ]
+
+  sources += common_player_sources
+
+  configs += [ "//starboard/build/config:starboard_implementation" ]
+
+  public_deps = [
+    ":starboard_base_symbolize",
+    "//starboard:starboard_headers_only",
+    "//starboard/common/",
+    "//starboard/shared/ffmpeg:ffmpeg_linked",
+    "//starboard/shared/starboard/media:media_util",
+    "//starboard/shared/starboard/player/filter:filter_based_player_sources",
+  ]
+  if (sb_is_evergreen_compatible) {
+    public_deps += [ "//starboard/elf_loader:evergreen_config" ]
+  }
+  if (sb_is_evergreen_compatible && !sb_evergreen_compatible_enable_lite) {
+    public_deps += [ "//starboard/loader_app:pending_restart" ]
+  }
+
+  deps = [
+    "//third_party/libevent",
+    "//third_party/opus",
+  ]
+  if (sb_evergreen_compatible_use_libunwind) {
+    deps += [ "//third_party/llvm-project/libunwind:unwind_starboard" ]
+  }
+}
+
+static_library("starboard_base_symbolize") {
+  sources = [
+    "//base/third_party/symbolize/demangle.cc",
+    "//base/third_party/symbolize/symbolize.cc",
+  ]
+
+  public_deps = [ "//starboard/elf_loader:evergreen_info" ]
+}
diff --git a/src/starboard/raspi/shared/platform_configuration/BUILD.gn b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
new file mode 100644
index 0000000..fbbab79
--- /dev/null
+++ b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
@@ -0,0 +1,195 @@
+# Copyright 2021 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.
+
+declare_args() {
+  raspi_home = getenv("RASPI_HOME")
+}
+
+config("compiler_flags") {
+  cflags = []
+  cflags_c = []
+  cflags_cc = []
+  defines = []
+  ldflags = []
+
+  defines += [
+    # By default, <EGL/eglplatform.h> pulls in some X11 headers that have some
+    # nasty macros (|Status|, for example) that conflict with Chromium base.
+    "MESA_EGL_NO_X11_HEADERS",
+
+    # Cobalt on Linux flag
+    "COBALT_LINUX",
+    "__STDC_FORMAT_MACROS",  # so that we get PRI*
+    "_GNU_SOURCE=1",
+  ]
+
+  if (is_debug) {
+    cflags += [ "-O0" ]
+    cflags_cc += [ "-frtti" ]
+  } else if (is_devel) {
+    cflags += [ "-O2" ]
+    cflags_cc += [ "-frtti" ]
+  } else {
+    cflags += [ "-Wno-unused-but-set-variable" ]
+    cflags_cc += [ "-fno-rtti" ]
+  }
+
+  ldflags += [
+    "--sysroot=$raspi_home/busterroot",
+
+    # This is a quirk of Raspbian, these are required to link any GL-related
+    # libraries.
+    "-L$raspi_home/busterroot/opt/vc/lib",
+    "-Wl,-rpath=$raspi_home/busterroot/opt/vc/lib",
+    "-L$raspi_home/busterroot/usr/lib/arm-linux-gnueabihf",
+    "-Wl,-rpath=$raspi_home/busterroot/usr/lib/arm-linux-gnueabihf",
+    "-L$raspi_home/busterroot/lib/arm-linux-gnueabihf",
+    "-Wl,-rpath=$raspi_home/busterroot/lib/arm-linux-gnueabihf",
+
+    # Cleanup unused sections
+    "-Wl,-gc-sections",
+    "-Wl,--unresolved-symbols=ignore-in-shared-libs",
+  ]
+
+  cflags += [
+    # Generated by Audio Renderer and Audio Sink implementations.
+    "-Wno-reorder",
+
+    # Generated by code in the raspi/shared/open_max.
+    "-Wno-sign-compare",
+
+    # Generated by many starboard implementation files.
+    "-Wno-unused-parameter",
+    "-Wno-unused-variable",
+  ]
+
+  cflags += [
+    # Force char to be signed.
+    "-fsigned-char",
+
+    # Disable strict aliasing.
+    "-fno-strict-aliasing",
+
+    # Allow Skia"s SkVx.h to convert between vectors of different element
+    # types or number of subparts.
+    "-flax-vector-conversions",
+
+    # To support large files
+    "-D_FILE_OFFSET_BITS=64",
+
+    # Suppress some warnings that will be hard to fix.
+    "-Wno-unused-local-typedefs",
+    "-Wno-unused-result",
+    "-Wno-unused-function",
+    "-Wno-deprecated-declarations",
+    "-Wno-missing-field-initializers",
+    "-Wno-extra",
+    "-Wno-comment",  # Talk to my lawyer.
+    "-Wno-narrowing",
+    "-Wno-unknown-pragmas",
+    "-Wno-type-limits",  # TODO: We should actually look into these.
+
+    # It"s OK not to use some input parameters. Note that the order
+    # matters: Wall implies Wunused-parameter and Wno-unused-parameter
+    # has no effect if specified before Wall.
+    "-Wno-unused-parameter",
+
+    # Specify the sysroot with all your include dependencies.
+    "--sysroot=$raspi_home/busterroot",
+
+    # This is a quirk of Raspbian, these are required to include any
+    # GL-related headers.
+    "-I$raspi_home/busterroot/opt/vc/include",
+    "-I$raspi_home/busterroot/opt/vc/include/interface/vcos/pthreads",
+    "-I$raspi_home/busterroot/opt/vc/include/interface/vmcs_host/linux",
+    "-I$raspi_home/busterroot/usr/include/arm-linux-gnueabihf",
+  ]
+
+  if (!cobalt_fastbuild && (is_debug || is_devel)) {
+    cflags += [ "-g" ]
+  }
+
+  cflags_c += [ "-std=c11" ]
+  cflags_cc += [
+    "-std=gnu++14",
+    "-Wno-literal-suffix",
+  ]
+
+  if (sb_pedantic_warnings) {
+    cflags += [
+      "-Wall",
+      "-Wextra",
+      "-Wunreachable-code",
+
+      # Raspi toolchain is based off an old version of gcc, which
+      # falsely flags some code.  That same code does not warn with gcc 6.3.
+      # This decision should be revisited after raspi toolchain is upgraded.
+      "-Wno-maybe-uninitialized",
+
+      #TODO: Renable -Werror after fixing all warnings.
+      #"-Werror",
+      "-Wno-expansion-to-defined",
+      "-Wno-implicit-fallthrough",
+    ]
+  } else {
+    cflags += [
+      # Do not warn for implicit type conversions that may change a value.
+      "-Wno-conversion",
+    ]
+  }
+}
+
+config("platform_configuration") {
+  libs = [
+    "asound",
+    "avcodec",
+    "avformat",
+    "avutil",
+    ":libpthread.so.0",
+    "pthread",
+    "rt",
+    "openmaxil",
+    "bcm_host",
+    "vcos",
+    "vchiq_arm",
+    "brcmGLESv2",
+    "brcmEGL",
+
+    # Static libs must be last, to avoid __dlopen linker errors
+    "EGL_static",
+    "GLESv2_static",
+  ]
+
+  configs = [ "//starboard/raspi/shared/platform_configuration:compiler_flags" ]
+}
+
+config("speed") {
+  cflags = [
+    "-O2",
+
+    # Compile symbols in separate sections
+    "-ffunction-sections",
+    "-fdata-sections",
+  ]
+}
+
+config("size") {
+  cflags = [
+    "-Os",
+
+    # Compile symbols in separate sections
+    "-ffunction-sections",
+    "-fdata-sections",
+  ]
+}
diff --git a/src/starboard/raspi/shared/platform_configuration/configuration.gni b/src/starboard/raspi/shared/platform_configuration/configuration.gni
new file mode 100644
index 0000000..c96fc14
--- /dev/null
+++ b/src/starboard/raspi/shared/platform_configuration/configuration.gni
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+import("//starboard/build/config/base_configuration.gni")
+
+sb_pedantic_warnings = true
+sb_static_contents_output_data_dir = "$root_out_dir/content"
+
+sabi_path = "//starboard/sabi/arm/hardfp/sabi-v$sb_api_version.json"
diff --git a/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc b/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
index dbb1d9e..5127ae4 100644
--- a/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/adaptive_audio_decoder_test.cc
@@ -362,8 +362,8 @@
     return test_params;
   }
 
-  vector<const char*> supported_files =
-      GetSupportedAudioTestFiles(kExcludeHeaac, 6);
+  vector<const char*> supported_files = GetSupportedAudioTestFiles(
+      kExcludeHeaac, 6, "audiopassthrough=\"false\"");
 
   // Generate test cases. For example, we have |supported_files| [A, B, C].
   // Add tests A->A, A->B, A->C, B->A, B->B, B->C, C->A, C->B and C->C.
diff --git a/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc b/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
index 74b8adf..00933f3 100644
--- a/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
+++ b/src/starboard/shared/starboard/player/filter/testing/audio_decoder_test.cc
@@ -635,7 +635,10 @@
 INSTANTIATE_TEST_CASE_P(
     AudioDecoderTests,
     AudioDecoderTest,
-    Combine(ValuesIn(GetSupportedAudioTestFiles(kIncludeHeaac, 6)), Bool()));
+    Combine(ValuesIn(GetSupportedAudioTestFiles(kIncludeHeaac,
+                                                6,
+                                                "audiopassthrough=\"false\"")),
+            Bool()));
 
 }  // namespace
 }  // namespace testing
diff --git a/src/third_party/inspector_protocol/crdtp/json_platform.cc b/src/third_party/inspector_protocol/crdtp/json_platform.cc
index 59c8deb..21e26ce 100644
--- a/src/third_party/inspector_protocol/crdtp/json_platform.cc
+++ b/src/third_party/inspector_protocol/crdtp/json_platform.cc
@@ -16,6 +16,9 @@
 namespace json {
 namespace platform {
 bool StrToD(const char* str, double* result) {
+#if SB_IS(EVERGREEN)
+#error "The std::locale::classic() is not supported for Evergreen. Please use base::StringToDouble()."
+#endif
   std::istringstream is(str);
   is.imbue(std::locale::classic());
   is >> *result;
@@ -23,6 +26,9 @@
 }
 
 std::string DToStr(double value) {
+#if SB_IS(EVERGREEN)
+#error "The std::locale::classic() is not supported for Evergreen. Please use base::NumberToString()."
+#endif
   std::stringstream ss;
   ss.imbue(std::locale::classic());
   ss << value;
diff --git a/src/third_party/libevent/evdns.c b/src/third_party/libevent/evdns.c
index 05fe594..d72fdaa 100644
--- a/src/third_party/libevent/evdns.c
+++ b/src/third_party/libevent/evdns.c
@@ -783,7 +783,6 @@
 
 	for(;;) {
 		u8 label_len;
-		if (j >= length) return -1;
 		GET8(label_len);
 		if (!label_len) break;
 		if (label_len & 0xc0) {
@@ -804,6 +803,7 @@
 			*cp++ = '.';
 		}
 		if (cp + label_len >= end) return -1;
+		if (j + label_len > length) return -1;
 		memcpy(cp, packet + j, label_len);
 		cp += label_len;
 		j += label_len;
diff --git a/src/third_party/libjpeg-turbo/BUILD.gn b/src/third_party/libjpeg-turbo/BUILD.gn
new file mode 100644
index 0000000..d566340
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/BUILD.gn
@@ -0,0 +1,346 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Do not use the targets in this file unless you need a certain libjpeg
+# implementation. Use the meta target //third_party:jpeg instead.
+
+import("//build/config/sanitizers/sanitizers.gni")
+if (current_cpu == "arm" || current_cpu == "arm64") {
+  import("//build/config/arm.gni")
+}
+
+assert(!is_ios, "This is not used on iOS, don't drag it in unintentionally")
+
+source_set("libjpeg_headers") {
+  sources = [
+    "jconfig.h",
+    "jdct.h",
+    "jinclude.h",
+    "jmorecfg.h",
+    "jpeglib.h",
+    "jpeglibmangler.h",
+  ]
+  defines = [ "MANGLE_JPEG_NAMES" ]
+}
+
+if (current_cpu == "x86" || current_cpu == "x64") {
+  import("//third_party/nasm/nasm_assemble.gni")
+
+  nasm_assemble("simd_asm") {
+    defines = []
+    include_dirs = [ "simd/nasm/" ]
+
+    if (current_cpu == "x86") {
+      include_dirs += [ "simd/i386/" ]
+      sources = [
+        "simd/i386/jccolor-avx2.asm",
+        "simd/i386/jccolor-mmx.asm",
+        "simd/i386/jccolor-sse2.asm",
+        "simd/i386/jcgray-avx2.asm",
+        "simd/i386/jcgray-mmx.asm",
+        "simd/i386/jcgray-sse2.asm",
+        "simd/i386/jchuff-sse2.asm",
+        "simd/i386/jcphuff-sse2.asm",
+        "simd/i386/jcsample-avx2.asm",
+        "simd/i386/jcsample-mmx.asm",
+        "simd/i386/jcsample-sse2.asm",
+        "simd/i386/jdcolor-avx2.asm",
+        "simd/i386/jdcolor-mmx.asm",
+        "simd/i386/jdcolor-sse2.asm",
+        "simd/i386/jdmerge-avx2.asm",
+        "simd/i386/jdmerge-mmx.asm",
+        "simd/i386/jdmerge-sse2.asm",
+        "simd/i386/jdsample-avx2.asm",
+        "simd/i386/jdsample-mmx.asm",
+        "simd/i386/jdsample-sse2.asm",
+        "simd/i386/jfdctflt-3dn.asm",
+        "simd/i386/jfdctflt-sse.asm",
+        "simd/i386/jfdctfst-mmx.asm",
+        "simd/i386/jfdctfst-sse2.asm",
+        "simd/i386/jfdctint-avx2.asm",
+        "simd/i386/jfdctint-mmx.asm",
+        "simd/i386/jfdctint-sse2.asm",
+        "simd/i386/jidctflt-3dn.asm",
+        "simd/i386/jidctflt-sse.asm",
+        "simd/i386/jidctflt-sse2.asm",
+        "simd/i386/jidctfst-mmx.asm",
+        "simd/i386/jidctfst-sse2.asm",
+        "simd/i386/jidctint-avx2.asm",
+        "simd/i386/jidctint-mmx.asm",
+        "simd/i386/jidctint-sse2.asm",
+        "simd/i386/jidctred-mmx.asm",
+        "simd/i386/jidctred-sse2.asm",
+        "simd/i386/jquant-3dn.asm",
+        "simd/i386/jquant-mmx.asm",
+        "simd/i386/jquant-sse.asm",
+        "simd/i386/jquantf-sse2.asm",
+        "simd/i386/jquanti-avx2.asm",
+        "simd/i386/jquanti-sse2.asm",
+        "simd/i386/jsimdcpu.asm",
+      ]
+      defines += [
+        "__x86__",
+        "PIC",
+      ]
+    } else if (current_cpu == "x64") {
+      include_dirs += [ "simd/x86_64/" ]
+      sources = [
+        "simd/x86_64/jccolor-avx2.asm",
+        "simd/x86_64/jccolor-sse2.asm",
+        "simd/x86_64/jcgray-avx2.asm",
+        "simd/x86_64/jcgray-sse2.asm",
+        "simd/x86_64/jchuff-sse2.asm",
+        "simd/x86_64/jcphuff-sse2.asm",
+        "simd/x86_64/jcsample-avx2.asm",
+        "simd/x86_64/jcsample-sse2.asm",
+        "simd/x86_64/jdcolor-avx2.asm",
+        "simd/x86_64/jdcolor-sse2.asm",
+        "simd/x86_64/jdmerge-avx2.asm",
+        "simd/x86_64/jdmerge-sse2.asm",
+        "simd/x86_64/jdsample-avx2.asm",
+        "simd/x86_64/jdsample-sse2.asm",
+        "simd/x86_64/jfdctflt-sse.asm",
+        "simd/x86_64/jfdctfst-sse2.asm",
+        "simd/x86_64/jfdctint-avx2.asm",
+        "simd/x86_64/jfdctint-sse2.asm",
+        "simd/x86_64/jidctflt-sse2.asm",
+        "simd/x86_64/jidctfst-sse2.asm",
+        "simd/x86_64/jidctint-avx2.asm",
+        "simd/x86_64/jidctint-sse2.asm",
+        "simd/x86_64/jidctred-sse2.asm",
+        "simd/x86_64/jquantf-sse2.asm",
+        "simd/x86_64/jquanti-avx2.asm",
+        "simd/x86_64/jquanti-sse2.asm",
+        "simd/x86_64/jsimdcpu.asm",
+      ]
+      defines += [
+        "__x86_64__",
+        "PIC",
+      ]
+    }
+
+    if (is_win) {
+      defines += [ "MSVC" ]
+      if (current_cpu == "x86") {
+        defines += [ "WIN32" ]
+      } else {
+        defines += [ "WIN64" ]
+      }
+    } else if (is_mac || is_ios) {
+      defines += [ "MACHO" ]
+    } else if (is_linux || is_android || is_fuchsia || is_chromeos) {
+      defines += [ "ELF" ]
+    }
+  }
+}
+
+static_library("simd") {
+  include_dirs = [ "." ]
+  deps = [ ":libjpeg_headers" ]
+
+  if (current_cpu == "x86") {
+    deps += [ ":simd_asm" ]
+    sources = [ "simd/i386/jsimd.c" ]
+  } else if (current_cpu == "x64") {
+    deps += [ ":simd_asm" ]
+    sources = [ "simd/x86_64/jsimd.c" ]
+  } else if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
+    include_dirs += [ "simd/arm/" ]
+
+    sources = [
+      "simd/arm/jccolor-neon.c",
+      "simd/arm/jcgray-neon.c",
+      "simd/arm/jcphuff-neon.c",
+      "simd/arm/jcsample-neon.c",
+      "simd/arm/jdcolor-neon.c",
+      "simd/arm/jdmerge-neon.c",
+      "simd/arm/jdsample-neon.c",
+      "simd/arm/jfdctfst-neon.c",
+      "simd/arm/jfdctint-neon.c",
+      "simd/arm/jidctfst-neon.c",
+      "simd/arm/jidctint-neon.c",
+      "simd/arm/jidctred-neon.c",
+      "simd/arm/jquanti-neon.c",
+    ]
+    if (current_cpu == "arm") {
+      sources += [
+        "simd/arm/aarch32/jchuff-neon.c",
+        "simd/arm/aarch32/jsimd.c",
+      ]
+    } else if (current_cpu == "arm64") {
+      sources += [
+        "simd/arm/aarch64/jchuff-neon.c",
+        "simd/arm/aarch64/jsimd.c",
+      ]
+    }
+
+    defines = [ "NEON_INTRINSICS" ]
+
+    configs -= [ "//build/config/compiler:default_optimization" ]
+    configs += [ "//build/config/compiler:optimize_speed" ]
+  } else {
+    sources = [ "jsimd_none.c" ]
+  }
+
+  if (is_win) {
+    cflags = [ "/wd4245" ]
+  }
+}
+
+config("libjpeg_config") {
+  include_dirs = [ "." ]
+}
+
+static_library("libjpeg") {
+  sources = [
+    "jcapimin.c",
+    "jcapistd.c",
+    "jccoefct.c",
+    "jccolor.c",
+    "jcdctmgr.c",
+    "jchuff.c",
+    "jcicc.c",
+    "jcinit.c",
+    "jcmainct.c",
+    "jcmarker.c",
+    "jcmaster.c",
+    "jcomapi.c",
+    "jcparam.c",
+    "jcphuff.c",
+    "jcprepct.c",
+    "jcsample.c",
+    "jctrans.c",
+    "jdapimin.c",
+    "jdapistd.c",
+    "jdatadst.c",
+    "jdatasrc.c",
+    "jdcoefct.c",
+    "jdcolor.c",
+    "jddctmgr.c",
+    "jdhuff.c",
+    "jdicc.c",
+    "jdinput.c",
+    "jdmainct.c",
+    "jdmarker.c",
+    "jdmaster.c",
+    "jdmerge.c",
+    "jdphuff.c",
+    "jdpostct.c",
+    "jdsample.c",
+    "jdtrans.c",
+    "jerror.c",
+    "jfdctflt.c",
+    "jfdctfst.c",
+    "jfdctint.c",
+    "jidctflt.c",
+    "jidctfst.c",
+    "jidctint.c",
+    "jidctred.c",
+    "jmemmgr.c",
+    "jmemnobs.c",
+    "jpeg_nbits_table.c",
+    "jquant1.c",
+    "jquant2.c",
+    "jutils.c",
+  ]
+
+  defines = [
+    "WITH_SIMD",
+    "NO_GETENV",
+  ]
+
+  configs += [ ":libjpeg_config" ]
+
+  public_configs = [ ":libjpeg_config" ]
+  public_deps = [ ":libjpeg_headers" ]
+
+  # MemorySanitizer doesn't support assembly code, so keep it disabled in x86
+  # and x64 MSan builds for now.
+  if (is_msan && (current_cpu == "x86" || current_cpu == "x64")) {
+    sources += [ "jsimd_none.c" ]
+  } else {
+    public_deps += [ ":simd" ]
+
+    if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
+      defines += [ "NEON_INTRINSICS" ]
+    }
+  }
+}
+
+static_library("turbojpeg") {
+  sources = [
+    "jdatadst-tj.c",
+    "jdatasrc-tj.c",
+    "rdbmp.c",
+    "rdppm.c",
+    "transupp.c",
+    "turbojpeg.c",
+    "wrbmp.c",
+    "wrppm.c",
+  ]
+
+  defines = [
+    "WITH_SIMD",
+    "BMP_SUPPORTED",
+    "PPM_SUPPORTED",
+  ]
+
+  configs += [ ":libjpeg_config" ]
+
+  public_configs = [ ":libjpeg_config" ]
+  public_deps = [ ":libjpeg" ]
+}
+
+if (build_with_chromium) {
+  import("//testing/test.gni")
+
+  test("libjpeg_turbo_unittests") {
+    testonly = true
+
+    sources = [
+      "cdjpeg.c",
+      "cjpeg.c",
+      "djpeg.c",
+      "gtest/cjpeg-gtest-wrapper.cpp",
+      "gtest/djpeg-gtest-wrapper.cpp",
+      "gtest/gtest-utils.cpp",
+      "gtest/jpegtran-gtest-wrapper.cpp",
+      "gtest/tjbench-gtest-wrapper.cpp",
+      "gtest/tjunittest-gtest-wrapper.cpp",
+      "jpegtran.c",
+      "md5/md5.c",
+      "md5/md5hl.c",
+      "rdcolmap.c",
+      "rdgif.c",
+      "rdswitch.c",
+      "tjbench.c",
+      "tjunittest.c",
+      "tjutil.c",
+    ]
+
+    deps = [
+      ":turbojpeg",
+      "//base",
+      "//testing/gtest",
+      "//testing/gtest:gtest_main",
+    ]
+
+    data = [ "testimages/" ]
+
+    defines = [
+      "GTEST",
+      "WITH_SIMD",
+      "BMP_SUPPORTED",
+      "PPM_SUPPORTED",
+    ]
+
+    include_dirs = [
+      "//third_party/googletest/src/googletest/include/gtest",
+      ".",
+    ]
+
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/BUILDING.md b/src/third_party/libjpeg-turbo/BUILDING.md
index 429963e..f91abcd 100644
--- a/src/third_party/libjpeg-turbo/BUILDING.md
+++ b/src/third_party/libjpeg-turbo/BUILDING.md
@@ -12,16 +12,18 @@
 
 - [NASM](http://www.nasm.us) or [YASM](http://yasm.tortall.net)
   (if building x86 or x86-64 SIMD extensions)
-  * If using NASM, 2.10 or later is required.
-  * If using NASM, 2.10 or later (except 2.11.08) is required for an x86-64 Mac
-    build (2.11.08 does not work properly with libjpeg-turbo's x86-64 SIMD code
-    when building macho64 objects.)  NASM or YASM can be obtained from
-    [MacPorts](http://www.macports.org/) or [Homebrew](http://brew.sh/).
+  * If using NASM, 2.13 or later is required.
   * If using YASM, 1.2.0 or later is required.
+  * If building on macOS, NASM or YASM can be obtained from
+    [MacPorts](http://www.macports.org/) or [Homebrew](http://brew.sh/).
      - NOTE: Currently, if it is desirable to hide the SIMD function symbols in
        Mac executables or shared libraries that statically link with
-       libjpeg-turbo, then YASM must be used when building libjpeg-turbo.
+       libjpeg-turbo, then NASM 2.14 or later or YASM must be used when
+       building libjpeg-turbo.
   * If building on Windows, **nasm.exe**/**yasm.exe** should be in your `PATH`.
+  * NASM and YASM are located in the CRB (Code Ready Builder) repository on
+    Red Hat Enterprise Linux 8 and in the PowerTools repository on CentOS 8,
+    which is not enabled by default.
 
   The binary RPMs released by the NASM project do not work on older Linux
   systems, such as Red Hat Enterprise Linux 5.  On such systems, you can easily
@@ -44,34 +46,33 @@
 
 - If building the TurboJPEG Java wrapper, JDK or OpenJDK 1.5 or later is
   required.  Most modern Linux distributions, as well as Solaris 10 and later,
-  include JDK or OpenJDK.  On OS X 10.5 and 10.6, it will be necessary to
-  install the Java Developer Package, which can be downloaded from
-  <http://developer.apple.com/downloads> (Apple ID required.)  For other
-  systems, you can obtain the Oracle Java Development Kit from
-  <http://www.java.com>.
+  include JDK or OpenJDK.  For other systems, you can obtain the Oracle Java
+  Development Kit from
+  <http://www.oracle.com/technetwork/java/javase/downloads>.
 
+  * If using JDK 11 or later, CMake 3.10.x or later must also be used.
 
 ### Windows
 
 - Microsoft Visual C++ 2005 or later
 
   If you don't already have Visual C++, then the easiest way to get it is by
-  installing the
-  [Windows SDK](http://msdn.microsoft.com/en-us/windows/bb980924.aspx).
-  The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
-  everything necessary to build libjpeg-turbo.
+  installing
+  [Visual Studio Community Edition](https://visualstudio.microsoft.com),
+  which includes everything necessary to build libjpeg-turbo.
 
-  * You can also use Microsoft Visual Studio Express/Community Edition, which
-    is a free download.  (NOTE: versions prior to 2012 can only be used to
-    build 32-bit code.)
+  * You can also download and install the standalone Windows SDK (for Windows 7
+    or later), which includes command-line versions of the 32-bit and 64-bit
+    Visual C++ compilers.
   * If you intend to build libjpeg-turbo from the command line, then add the
     appropriate compiler and SDK directories to the `INCLUDE`, `LIB`, and
     `PATH` environment variables.  This is generally accomplished by
-    executing `vcvars32.bat` or `vcvars64.bat` and `SetEnv.cmd`.
-    `vcvars32.bat` and `vcvars64.bat` are part of Visual C++ and are located in
-    the same directory as the compiler.  `SetEnv.cmd` is part of the Windows
-    SDK.  You can pass optional arguments to `SetEnv.cmd` to specify a 32-bit
-    or 64-bit build environment.
+    executing `vcvars32.bat` or `vcvars64.bat`, which are located in the same
+    directory as the compiler.
+  * If built with Visual C++ 2015 or later, the libjpeg-turbo static libraries
+    cannot be used with earlier versions of Visual C++, and vice versa.
+  * The libjpeg API DLL (**jpeg{version}.dll**) will depend on the C run-time
+    DLLs corresponding to the version of Visual C++ that was used to build it.
 
    ... OR ...
 
@@ -83,7 +84,10 @@
   appropriate compiler paths automatically set.
 
 - If building the TurboJPEG Java wrapper, JDK 1.5 or later is required.  This
-  can be downloaded from <http://www.java.com>.
+  can be downloaded from
+  <http://www.oracle.com/technetwork/java/javase/downloads>.
+
+  * If using JDK 11 or later, CMake 3.10.x or later must also be used.
 
 
 Out-of-Tree Builds
@@ -99,6 +103,13 @@
 directory.  For in-tree builds, these directories are the same.
 
 
+Ninja
+-----
+
+In all of the procedures and recipes below, replace `make` with `ninja` and
+`Unix Makefiles` with `Ninja` if using Ninja.
+
+
 Build Procedure
 ---------------
 
@@ -324,7 +335,7 @@
 -------------
 
 
-### 32-bit Build on 64-bit Linux/Unix/Mac
+### 32-bit Build on 64-bit Linux/Unix
 
 Use export/setenv to set the following environment variables before running
 CMake:
@@ -389,114 +400,25 @@
 Building libjpeg-turbo for iOS
 ------------------------------
 
-iOS platforms, such as the iPhone and iPad, use ARM processors, and all
-currently supported models include NEON instructions.  Thus, they can take
+iOS platforms, such as the iPhone and iPad, use Arm processors, and all
+currently supported models include Neon instructions.  Thus, they can take
 advantage of libjpeg-turbo's SIMD extensions to significantly accelerate JPEG
 compression/decompression.  This section describes how to build libjpeg-turbo
 for these platforms.
 
 
-### Additional build requirements
+### Armv8 (64-bit)
 
-- For configurations that require [gas-preprocessor.pl]
-  (https://raw.githubusercontent.com/libjpeg-turbo/gas-preprocessor/master/gas-preprocessor.pl),
-  it should be installed in your `PATH`.
-
-
-### ARMv7 (32-bit)
-
-**gas-preprocessor.pl required**
-
-The following scripts demonstrate how to build libjpeg-turbo to run on the
-iPhone 3GS-4S/iPad 1st-3rd Generation and newer:
-
-#### Xcode 4.2 and earlier (LLVM-GCC)
-
-    IOS_PLATFORMDIR=/Developer/Platforms/iPhoneOS.platform
-    IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
-    export CFLAGS="-mfloat-abi=softfp -march=armv7 -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -miphoneos-version-min=3.0"
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Darwin)
-    set(CMAKE_SYSTEM_PROCESSOR arm)
-    set(CMAKE_C_COMPILER ${IOS_PLATFORMDIR}/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2)
-    EOF
-
-    cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
-      [additional CMake flags] {source_directory}
-    make
-
-#### Xcode 4.3-4.6 (LLVM-GCC)
-
-Same as above, but replace the first line with:
-
-    IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
-
-#### Xcode 5 and later (Clang)
-
-    IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
-    IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
-    export CFLAGS="-mfloat-abi=softfp -arch armv7 -miphoneos-version-min=3.0"
-    export ASMFLAGS="-no-integrated-as"
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Darwin)
-    set(CMAKE_SYSTEM_PROCESSOR arm)
-    set(CMAKE_C_COMPILER /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
-    EOF
-
-    cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
-      [additional CMake flags] {source_directory}
-    make
-
-
-### ARMv7s (32-bit)
-
-**gas-preprocessor.pl required**
-
-The following scripts demonstrate how to build libjpeg-turbo to run on the
-iPhone 5/iPad 4th Generation and newer:
-
-#### Xcode 4.5-4.6 (LLVM-GCC)
-
-    IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
-    IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
-    export CFLAGS="-Wall -mfloat-abi=softfp -march=armv7s -mcpu=swift -mtune=swift -mfpu=neon -miphoneos-version-min=6.0"
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Darwin)
-    set(CMAKE_SYSTEM_PROCESSOR arm)
-    set(CMAKE_C_COMPILER ${IOS_PLATFORMDIR}/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2)
-    EOF
-
-    cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
-      [additional CMake flags] {source_directory}
-    make
-
-#### Xcode 5 and later (Clang)
-
-Same as the ARMv7 build procedure for Xcode 5 and later, except replace the
-compiler flags as follows:
-
-    export CFLAGS="-Wall -mfloat-abi=softfp -arch armv7s -miphoneos-version-min=6.0"
-
-
-### ARMv8 (64-bit)
-
-**gas-preprocessor.pl required if using Xcode < 6**
+**Xcode 5 or later required, Xcode 6.3.x or later recommended**
 
 The following script demonstrates how to build libjpeg-turbo to run on the
 iPhone 5S/iPad Mini 2/iPad Air and newer.
 
     IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
     IOS_SYSROOT=($IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk)
-    export CFLAGS="-Wall -arch arm64 -miphoneos-version-min=7.0 -funwind-tables"
+    export CFLAGS="-Wall -arch arm64 -miphoneos-version-min=8.0 -funwind-tables"
+
+    cd {build_directory}
 
     cat <<EOF >toolchain.cmake
     set(CMAKE_SYSTEM_NAME Darwin)
@@ -504,94 +426,69 @@
     set(CMAKE_C_COMPILER /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
     EOF
 
-    cd {build_directory}
     cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
       -DCMAKE_OSX_SYSROOT=${IOS_SYSROOT[0]} \
       [additional CMake flags] {source_directory}
     make
 
-Once built, lipo can be used to combine the ARMv7, v7s, and/or v8 variants into
-a universal library.
-
 
 Building libjpeg-turbo for Android
 ----------------------------------
 
-Building libjpeg-turbo for Android platforms requires the
+Building libjpeg-turbo for Android platforms requires v13b or later of the
 [Android NDK](https://developer.android.com/tools/sdk/ndk).
 
 
-### ARMv7 (32-bit)
+### Armv7 (32-bit)
+
+**NDK r19 or later with Clang recommended**
 
 The following is a general recipe script that can be modified for your specific
 needs.
 
     # Set these variables to suit your needs
-    NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/sdk/ndk-bundle}
-    BUILD_PLATFORM={the platform name for the NDK package you installed--
-      for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
-    TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc.  This corresponds to a
-      toolchain directory under ${NDK_PATH}/toolchains/.}
-    ANDROID_VERSION={The minimum version of Android to support-- for example,
+    NDK_PATH={full path to the NDK directory-- for example,
+      /opt/android/android-ndk-r16b}
+    TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r16b and earlier,
+      and "clang" must be used with NDK r17c and later}
+    ANDROID_VERSION={the minimum version of Android to support-- for example,
       "16", "19", etc.}
 
-    # It should not be necessary to modify the rest
-    HOST=arm-linux-androideabi
-    SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
-    export CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
-      -D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
-      -isystem ${NDK_PATH}/sysroot/usr/include \
-      -isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
-    export LDFLAGS=-pie
-    TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Linux)
-    set(CMAKE_SYSTEM_PROCESSOR arm)
-    set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
-    set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
-    EOF
-
     cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
+    cmake -G"Unix Makefiles" \
+      -DANDROID_ABI=armeabi-v7a \
+      -DANDROID_ARM_MODE=arm \
+      -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
+      -DANDROID_TOOLCHAIN=${TOOLCHAIN} \
+      -DCMAKE_ASM_FLAGS="--target=arm-linux-androideabi${ANDROID_VERSION}" \
+      -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
       [additional CMake flags] {source_directory}
     make
 
 
-### ARMv8 (64-bit)
+### Armv8 (64-bit)
+
+**Clang recommended**
 
 The following is a general recipe script that can be modified for your specific
 needs.
 
     # Set these variables to suit your needs
-    NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/sdk/ndk-bundle}
-    BUILD_PLATFORM={the platform name for the NDK package you installed--
-      for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
-    TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc.  This corresponds to a
-      toolchain directory under ${NDK_PATH}/toolchains/.}
-    ANDROID_VERSION={The minimum version of Android to support.  "21" or later
+    NDK_PATH={full path to the NDK directory-- for example,
+      /opt/android/android-ndk-r16b}
+    TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
+      and "clang" must be used with NDK r17c and later}
+    ANDROID_VERSION={the minimum version of Android to support.  "21" or later
       is required for a 64-bit build.}
 
-    # It should not be necessary to modify the rest
-    HOST=aarch64-linux-android
-    SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm64
-    export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
-      -isystem ${NDK_PATH}/sysroot/usr/include \
-      -isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
-    export LDFLAGS=-pie
-    TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Linux)
-    set(CMAKE_SYSTEM_PROCESSOR aarch64)
-    set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
-    set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
-    EOF
-
     cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
+    cmake -G"Unix Makefiles" \
+      -DANDROID_ABI=arm64-v8a \
+      -DANDROID_ARM_MODE=arm \
+      -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
+      -DANDROID_TOOLCHAIN=${TOOLCHAIN} \
+      -DCMAKE_ASM_FLAGS="--target=aarch64-linux-android${ANDROID_VERSION}" \
+      -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
       [additional CMake flags] {source_directory}
     make
 
@@ -602,33 +499,19 @@
 needs.
 
     # Set these variables to suit your needs
-    NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/sdk/ndk-bundle}
-    BUILD_PLATFORM={the platform name for the NDK package you installed--
-      for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
-    TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc.  This corresponds to a
-      toolchain directory under ${NDK_PATH}/toolchains/.}
+    NDK_PATH={full path to the NDK directory-- for example,
+      /opt/android/android-ndk-r16b}
+    TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
+      and "clang" must be used with NDK r17c and later}
     ANDROID_VERSION={The minimum version of Android to support-- for example,
       "16", "19", etc.}
 
-    # It should not be necessary to modify the rest
-    HOST=i686-linux-android
-    SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-x86
-    export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
-      -isystem ${NDK_PATH}/sysroot/usr/include \
-      -isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
-    export LDFLAGS=-pie
-    TOOLCHAIN=${NDK_PATH}/toolchains/x86-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Linux)
-    set(CMAKE_SYSTEM_PROCESSOR i386)
-    set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
-    set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
-    EOF
-
     cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
+    cmake -G"Unix Makefiles" \
+      -DANDROID_ABI=x86 \
+      -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
+      -DANDROID_TOOLCHAIN=${TOOLCHAIN} \
+      -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
       [additional CMake flags] {source_directory}
     make
 
@@ -639,42 +522,23 @@
 needs.
 
     # Set these variables to suit your needs
-    NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/sdk/ndk-bundle}
-    BUILD_PLATFORM={the platform name for the NDK package you installed--
-      for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
-    TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc.  This corresponds to a
-      toolchain directory under ${NDK_PATH}/toolchains/.}
-    ANDROID_VERSION={The minimum version of Android to support.  "21" or later
+    NDK_PATH={full path to the NDK directory-- for example,
+      /opt/android/android-ndk-r16b}
+    TOOLCHAIN={"gcc" or "clang"-- "gcc" must be used with NDK r14b and earlier,
+      and "clang" must be used with NDK r17c and later}
+    ANDROID_VERSION={the minimum version of Android to support.  "21" or later
       is required for a 64-bit build.}
 
-    # It should not be necessary to modify the rest
-    HOST=x86_64-linux-android
-    SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-x86_64
-    export CFLAGS="-D__ANDROID_API__=${ANDROID_VERSION} --sysroot=${SYSROOT} \
-      -isystem ${NDK_PATH}/sysroot/usr/include \
-      -isystem ${NDK_PATH}/sysroot/usr/include/${HOST}"
-    export LDFLAGS=-pie
-    TOOLCHAIN=${NDK_PATH}/toolchains/x86_64-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
-
-    cat <<EOF >toolchain.cmake
-    set(CMAKE_SYSTEM_NAME Linux)
-    set(CMAKE_SYSTEM_PROCESSOR x86_64)
-    set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${HOST}-gcc)
-    set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/${HOST})
-    EOF
-
     cd {build_directory}
-    cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake \
-      -DCMAKE_POSITION_INDEPENDENT_CODE=1 \
+    cmake -G"Unix Makefiles" \
+      -DANDROID_ABI=x86_64 \
+      -DANDROID_PLATFORM=android-${ANDROID_VERSION} \
+      -DANDROID_TOOLCHAIN=${TOOLCHAIN} \
+      -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \
       [additional CMake flags] {source_directory}
     make
 
 
-If building for Android 4.0.x (API level < 16) or earlier, remove
-`-DCMAKE_POSITION_INDEPENDENT_CODE=1` from the CMake arguments and `-pie` from
-`LDFLAGS`.
-
-
 Advanced CMake Options
 ----------------------
 
@@ -780,44 +644,23 @@
     make dmg
 
 Create Mac package/disk image.  This requires pkgbuild and productbuild, which
-are installed by default on OS X 10.7 and later and which can be obtained by
-installing Xcode 3.2.6 (with the "Unix Development" option) on OS X 10.6.
-Packages built in this manner can be installed on OS X 10.5 and later, but they
-must be built on OS X 10.6 or later.
+are installed by default on OS X/macOS 10.7 and later.
 
-    make udmg
+In order to create a Mac package/disk image that contains universal
+x86-64/Arm binaries, set the following CMake variable:
 
-This creates a Mac package/disk image that contains universal x86-64/i386/ARM
-binaries.  The following CMake variables control which architectures are
-included in the universal binaries.  Setting any of these variables to an empty
-string excludes that architecture from the package.
+* `ARMV8_BUILD`: Directory containing an Armv8 (64-bit) iOS or macOS build of
+  libjpeg-turbo to include in the universal binaries
 
-* `OSX_32BIT_BUILD`: Directory containing an i386 (32-bit) Mac build of
-  libjpeg-turbo (default: *{source_directory}*/osxx86)
-* `IOS_ARMV7_BUILD`: Directory containing an ARMv7 (32-bit) iOS build of
-  libjpeg-turbo (default: *{source_directory}*/iosarmv7)
-* `IOS_ARMV7S_BUILD`: Directory containing an ARMv7s (32-bit) iOS build of
-  libjpeg-turbo (default: *{source_directory}*/iosarmv7s)
-* `IOS_ARMV8_BUILD`: Directory containing an ARMv8 (64-bit) iOS build of
-  libjpeg-turbo (default: *{source_directory}*/iosarmv8)
-
-You should first use CMake to configure i386, ARMv7, ARMv7s, and/or ARMv8
-sub-builds of libjpeg-turbo (see "Build Recipes" and "Building libjpeg-turbo
-for iOS" above) in build directories that match those specified in the
-aforementioned CMake variables.  Next, configure the primary build of
-libjpeg-turbo as an out-of-tree build, and build it.  Once the primary build
-has been built, run `make udmg` from the build directory.  The packaging system
-will build the sub-builds, use lipo to combine them into a single set of
-universal binaries, then package the universal binaries in the same manner as
-`make dmg`.
-
-
-Cygwin
-------
-
-    make cygwinpkg
-
-Build a Cygwin binary package.
+You should first use CMake to configure an Armv8 sub-build of libjpeg-turbo
+(see "Building libjpeg-turbo for iOS" above, if applicable) in a build
+directory that matches the one specified in the aforementioned CMake variable.
+Next, configure the primary (x86-64) build of libjpeg-turbo as an out-of-tree
+build, specifying the aforementioned CMake variable, and build it.  Once the
+primary build has been built, run `make dmg` from the build directory.  The
+packaging system will build the sub-build, use lipo to combine it with the
+primary build into a single set of universal binaries, then package the
+universal binaries.
 
 
 Windows
diff --git a/src/third_party/libjpeg-turbo/Brewfile b/src/third_party/libjpeg-turbo/Brewfile
deleted file mode 100644
index 4a9cb3d..0000000
--- a/src/third_party/libjpeg-turbo/Brewfile
+++ /dev/null
@@ -1,4 +0,0 @@
-brew 'yasm'
-brew 'gcc@5'
-brew 'md5sha1sum'
-cask 'Caskroom/versions/java6'
diff --git a/src/third_party/libjpeg-turbo/CMakeLists.txt b/src/third_party/libjpeg-turbo/CMakeLists.txt
deleted file mode 100644
index bea98b6..0000000
--- a/src/third_party/libjpeg-turbo/CMakeLists.txt
+++ /dev/null
@@ -1,1383 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12)
-
-project(libjpeg-turbo C)
-set(VERSION 1.5.91)
-string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
-list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
-list(GET VERSION_TRIPLET 1 VERSION_MINOR)
-list(GET VERSION_TRIPLET 2 VERSION_REVISION)
-function(pad_number NUMBER OUTPUT_LEN)
-  string(LENGTH "${${NUMBER}}" INPUT_LEN)
-  if(INPUT_LEN LESS OUTPUT_LEN)
-    math(EXPR ZEROES "${OUTPUT_LEN} - ${INPUT_LEN} - 1")
-    set(NUM ${${NUMBER}})
-    foreach(C RANGE ${ZEROES})
-      set(NUM "0${NUM}")
-    endforeach()
-    set(${NUMBER} ${NUM} PARENT_SCOPE)
-  endif()
-endfunction()
-pad_number(VERSION_MINOR 3)
-pad_number(VERSION_REVISION 3)
-set(LIBJPEG_TURBO_VERSION_NUMBER ${VERSION_MAJOR}${VERSION_MINOR}${VERSION_REVISION})
-
-string(TIMESTAMP DEFAULT_BUILD "%Y%m%d")
-set(BUILD ${DEFAULT_BUILD} CACHE STRING "Build string (default: ${DEFAULT_BUILD})")
-
-# NOTE: On Windows, this does nothing except when using MinGW or Cygwin.
-# CMAKE_BUILD_TYPE has no meaning in Visual Studio, and it always defaults to
-# Debug when using NMake.
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
-
-message(STATUS "VERSION = ${VERSION}, BUILD = ${BUILD}")
-
-# Detect CPU type and whether we're building 64-bit or 32-bit code
-math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8")
-string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR_LC)
-if(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86_64" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "amd64" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "i[0-9]86" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "x86" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "ia32")
-  if(BITS EQUAL 64)
-    set(CPU_TYPE x86_64)
-  else()
-    set(CPU_TYPE i386)
-  endif()
-  if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ${CPU_TYPE})
-    set(CMAKE_SYSTEM_PROCESSOR ${CPU_TYPE})
-  endif()
-elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "aarch64" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "arm*64*")
-  set(CPU_TYPE arm64)
-elseif(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "arm*")
-  set(CPU_TYPE arm)
-elseif(CMAKE_SYSTEM_PROCESSOR_LC MATCHES "ppc*" OR
-  CMAKE_SYSTEM_PROCESSOR_LC MATCHES "powerpc*")
-  set(CPU_TYPE powerpc)
-else()
-  set(CPU_TYPE ${CMAKE_SYSTEM_PROCESSOR_LC})
-endif()
-message(STATUS "${BITS}-bit build (${CPU_TYPE})")
-
-
-###############################################################################
-# INSTALL DIRECTORIES
-###############################################################################
-
-if(WIN32)
-  if(MSVC)
-    set(CMAKE_INSTALL_DEFAULT_PREFIX "c:/${CMAKE_PROJECT_NAME}")
-  else()
-    set(CMAKE_INSTALL_DEFAULT_PREFIX "c:/${CMAKE_PROJECT_NAME}-gcc")
-  endif()
-  if(BITS EQUAL 64)
-    set(CMAKE_INSTALL_DEFAULT_PREFIX "${CMAKE_INSTALL_DEFAULT_PREFIX}64")
-  endif()
-else()
-  set(CMAKE_INSTALL_DEFAULT_PREFIX /opt/${CMAKE_PROJECT_NAME})
-endif()
-if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
-  set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_DEFAULT_PREFIX}" CACHE PATH
-    "Directory into which to install ${CMAKE_PROJECT_NAME} (default: ${CMAKE_INSTALL_DEFAULT_PREFIX})"
-    FORCE)
-endif()
-message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
-
-# When the prefix is /opt/${CMAKE_PROJECT_NAME}, we assume that an "official"
-# build is being created, and thus we install things into specific locations.
-
-if(CMAKE_INSTALL_PREFIX STREQUAL "${CMAKE_INSTALL_DEFAULT_PREFIX}")
-  set(CMAKE_INSTALL_DEFAULT_DATAROOTDIR "")
-  set(CMAKE_INSTALL_DEFAULT_DOCDIR "<CMAKE_INSTALL_DATAROOTDIR>/doc")
-  set(CMAKE_INSTALL_DEFAULT_JAVADIR "<CMAKE_INSTALL_DATAROOTDIR>/classes")
-  if(UNIX AND NOT APPLE)
-    if(BITS EQUAL 64)
-      set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib64")
-    else()
-      set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib32")
-    endif()
-  endif()
-endif()
-
-include(cmakescripts/GNUInstallDirs.cmake)
-
-set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})
-
-macro(report_directory var)
-  if(CMAKE_INSTALL_${var} STREQUAL CMAKE_INSTALL_FULL_${var})
-    message(STATUS "CMAKE_INSTALL_${var} = ${CMAKE_INSTALL_${var}}")
-  else()
-    message(STATUS "CMAKE_INSTALL_${var} = ${CMAKE_INSTALL_${var}} (${CMAKE_INSTALL_FULL_${var}})")
-  endif()
-  mark_as_advanced(CLEAR CMAKE_INSTALL_${var})
-endmacro()
-
-set(DIRLIST "BINDIR;DATAROOTDIR;DOCDIR;INCLUDEDIR;LIBDIR")
-if(UNIX)
-  list(APPEND DIRLIST "MANDIR")
-endif()
-foreach(dir ${DIRLIST})
-  report_directory(${dir})
-endforeach()
-
-
-###############################################################################
-# CONFIGURATION OPTIONS
-###############################################################################
-
-macro(boolean_number var)
-  if(${var})
-    set(${var} 1)
-  else()
-    set(${var} 0)
-  endif()
-endmacro()
-
-option(ENABLE_SHARED "Build shared libraries" TRUE)
-boolean_number(ENABLE_SHARED)
-option(ENABLE_STATIC "Build static libraries" TRUE)
-boolean_number(ENABLE_STATIC)
-option(REQUIRE_SIMD "Generate a fatal error if SIMD extensions are not available for this platform (default is to fall back to a non-SIMD build)" FALSE)
-boolean_number(REQUIRE_SIMD)
-option(WITH_12BIT "Encode/decode JPEG images with 12-bit samples (implies WITH_ARITH_DEC=0 WITH_ARITH_ENC=0 WITH_JAVA=0 WITH_SIMD=0 WITH_TURBOJPEG=0 )" FALSE)
-boolean_number(WITH_12BIT)
-option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE)
-boolean_number(WITH_ARITH_DEC)
-option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE)
-boolean_number(WITH_ARITH_ENC)
-option(WITH_JAVA "Build Java wrapper for the TurboJPEG API library (implies ENABLE_SHARED=1)" FALSE)
-boolean_number(WITH_JAVA)
-option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" FALSE)
-boolean_number(WITH_JPEG7)
-option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" FALSE)
-boolean_number(WITH_JPEG8)
-option(WITH_MEM_SRCDST "Include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI" TRUE)
-boolean_number(WITH_MEM_SRCDST)
-option(WITH_SIMD "Include SIMD extensions, if available for this platform" TRUE)
-boolean_number(WITH_SIMD)
-option(WITH_TURBOJPEG "Include the TurboJPEG API library and associated test programs" TRUE)
-boolean_number(WITH_TURBOJPEG)
-
-macro(report_option var desc)
-  if(${var})
-    message(STATUS "${desc} enabled (${var} = ${${var}})")
-  else()
-    message(STATUS "${desc} disabled (${var} = ${${var}})")
-  endif()
-endmacro()
-
-if(WITH_JAVA)
-  set(ENABLE_SHARED 1)
-endif()
-
-# Explicitly setting CMAKE_POSITION_INDEPENDENT_CODE=FALSE disables PIC for all
-# targets, which will cause the shared library builds to fail.  Thus, if shared
-# libraries are enabled and CMAKE_POSITION_INDEPENDENT_CODE is explicitly set
-# to FALSE, we need to unset it, thus restoring the default behavior
-# (automatically using PIC for shared library targets.)
-if(DEFINED CMAKE_POSITION_INDEPENDENT_CODE AND
-  NOT CMAKE_POSITION_INDEPENDENT_CODE AND ENABLE_SHARED)
-  unset(CMAKE_POSITION_INDEPENDENT_CODE CACHE)
-endif()
-
-report_option(ENABLE_SHARED "Shared libraries")
-report_option(ENABLE_STATIC "Static libraries")
-
-if(WITH_12BIT)
-  set(WITH_ARITH_DEC 0)
-  set(WITH_ARITH_ENC 0)
-  set(WITH_JAVA 0)
-  set(WITH_SIMD 0)
-  set(WITH_TURBOJPEG 0)
-  set(BITS_IN_JSAMPLE 12)
-else()
-  set(BITS_IN_JSAMPLE 8)
-endif()
-report_option(WITH_12BIT "12-bit JPEG support")
-
-if(WITH_JPEG8 OR WITH_JPEG7)
-  set(WITH_ARITH_ENC 1)
-  set(WITH_ARITH_DEC 1)
-endif()
-if(WITH_JPEG8)
-  set(WITH_MEM_SRCDST 0)
-endif()
-
-if(WITH_ARITH_DEC)
-  set(D_ARITH_CODING_SUPPORTED 1)
-endif()
-if(NOT WITH_12BIT)
-  report_option(WITH_ARITH_DEC "Arithmetic decoding support")
-endif()
-
-if(WITH_ARITH_ENC)
-  set(C_ARITH_CODING_SUPPORTED 1)
-endif()
-if(NOT WITH_12BIT)
-  report_option(WITH_ARITH_ENC "Arithmetic encoding support")
-endif()
-
-if(NOT WITH_12BIT)
-  report_option(WITH_TURBOJPEG "TurboJPEG API library")
-  report_option(WITH_JAVA "TurboJPEG Java wrapper")
-endif()
-
-if(WITH_MEM_SRCDST)
-  set(MEM_SRCDST_SUPPORTED 1)
-  set(MEM_SRCDST_FUNCTIONS "global:  jpeg_mem_dest;  jpeg_mem_src;")
-endif()
-if(NOT WITH_JPEG8)
-  report_option(WITH_MEM_SRCDST "In-memory source/destination managers")
-endif()
-
-set(SO_AGE 2)
-if(WITH_MEM_SRCDST)
-  set(SO_AGE 3)
-endif()
-
-if(WITH_JPEG8)
-  set(JPEG_LIB_VERSION 80)
-elseif(WITH_JPEG7)
-  set(JPEG_LIB_VERSION 70)
-else()
-  set(JPEG_LIB_VERSION 62)
-endif()
-
-math(EXPR JPEG_LIB_VERSION_DIV10 "${JPEG_LIB_VERSION} / 10")
-math(EXPR JPEG_LIB_VERSION_MOD10 "${JPEG_LIB_VERSION} % 10")
-if(JPEG_LIB_VERSION STREQUAL "62")
-  set(DEFAULT_SO_MAJOR_VERSION ${JPEG_LIB_VERSION})
-else()
-  set(DEFAULT_SO_MAJOR_VERSION ${JPEG_LIB_VERSION_DIV10})
-endif()
-if(JPEG_LIB_VERSION STREQUAL "80")
-  set(DEFAULT_SO_MINOR_VERSION 2)
-else()
-  set(DEFAULT_SO_MINOR_VERSION 0)
-endif()
-
-# This causes SO_MAJOR_VERSION/SO_MINOR_VERSION to reset to defaults if
-# WITH_JPEG7 or WITH_JPEG8 has changed.
-if((DEFINED WITH_JPEG7_INT AND NOT WITH_JPEG7 EQUAL WITH_JPEG7_INT) OR
-  (DEFINED WITH_JPEG8_INT AND NOT WITH_JPEG8 EQUAL WITH_JPEG8_INT))
-  set(FORCE_SO_VERSION "FORCE")
-endif()
-set(WITH_JPEG7_INT ${WITH_JPEG7} CACHE INTERNAL "")
-set(WITH_JPEG8_INT ${WITH_JPEG8} CACHE INTERNAL "")
-
-set(SO_MAJOR_VERSION ${DEFAULT_SO_MAJOR_VERSION} CACHE STRING
-  "Major version of the libjpeg API shared library (default: ${DEFAULT_SO_MAJOR_VERSION})"
-  ${FORCE_SO_VERSION})
-set(SO_MINOR_VERSION ${DEFAULT_SO_MINOR_VERSION} CACHE STRING
-  "Minor version of the libjpeg API shared library (default: ${DEFAULT_SO_MINOR_VERSION})"
-  ${FORCE_SO_VERSION})
-
-set(JPEG_LIB_VERSION_DECIMAL "${JPEG_LIB_VERSION_DIV10}.${JPEG_LIB_VERSION_MOD10}")
-message(STATUS "Emulating libjpeg API/ABI v${JPEG_LIB_VERSION_DECIMAL} (WITH_JPEG7 = ${WITH_JPEG7}, WITH_JPEG8 = ${WITH_JPEG8})")
-message(STATUS "libjpeg API shared library version = ${SO_MAJOR_VERSION}.${SO_AGE}.${SO_MINOR_VERSION}")
-
-# Because the TurboJPEG API library uses versioned symbols and changes the
-# names of functions whenever they are modified in a backward-incompatible
-# manner, it is always backward-ABI-compatible with itself, so the major and
-# minor SO versions don't change.  However, we increase the middle number (the
-# SO "age") whenever functions are added to the API.
-set(TURBOJPEG_SO_MAJOR_VERSION 0)
-set(TURBOJPEG_SO_VERSION 0.2.0)
-
-
-###############################################################################
-# COMPILER SETTINGS
-###############################################################################
-
-if(MSVC)
-  option(WITH_CRT_DLL
-    "Link all ${CMAKE_PROJECT_NAME} libraries and executables with the C run-time DLL (msvcr*.dll) instead of the static C run-time library (libcmt*.lib.)  The default is to use the C run-time DLL only with the libraries and executables that need it."
-    FALSE)
-  if(NOT WITH_CRT_DLL)
-    # Use the static C library for all build types
-    foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
-      CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
-      if(${var} MATCHES "/MD")
-        string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
-      endif()
-    endforeach()
-  endif()
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /wd4996")
-endif()
-
-if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
-  # Use the maximum optimization level for release builds
-  foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
-    if(${var} MATCHES "-O2")
-      string(REGEX REPLACE "-O2" "-O3" ${var} "${${var}}")
-    endif()
-  endforeach()
-endif()
-
-if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-  if(CMAKE_C_COMPILER_ID MATCHES "SunPro")
-    # Use the maximum optimization level for release builds
-    foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
-      if(${var} MATCHES "-xO3")
-        string(REGEX REPLACE "-xO3" "-xO5" ${var} "${${var}}")
-      endif()
-      if(${var} MATCHES "-xO2")
-        string(REGEX REPLACE "-xO2" "-xO5" ${var} "${${var}}")
-      endif()
-    endforeach()
-  endif()
-endif()
-
-string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
-
-set(EFFECTIVE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-message(STATUS "Compiler flags = ${EFFECTIVE_C_FLAGS}")
-
-set(EFFECTIVE_LD_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-message(STATUS "Linker flags = ${EFFECTIVE_LD_FLAGS}")
-
-include(CheckCSourceCompiles)
-include(CheckIncludeFiles)
-include(CheckTypeSize)
-
-check_type_size("size_t" SIZE_T)
-check_type_size("unsigned long" UNSIGNED_LONG)
-
-if(SIZE_T EQUAL UNSIGNED_LONG)
-  check_c_source_compiles("int main(int argc, char **argv) { unsigned long a = argc;  return __builtin_ctzl(a); }"
-    HAVE_BUILTIN_CTZL)
-endif()
-if(MSVC)
-  check_include_files("intrin.h" HAVE_INTRIN_H)
-endif()
-
-if(UNIX)
-  # Check for headers
-  check_include_files(locale.h HAVE_LOCALE_H)
-  check_include_files(stddef.h HAVE_STDDEF_H)
-  check_include_files(stdlib.h HAVE_STDLIB_H)
-  check_include_files(sys/types.h NEED_SYS_TYPES_H)
-
-  # Check for functions
-  include(CheckSymbolExists)
-  check_symbol_exists(memset string.h HAVE_MEMSET)
-  check_symbol_exists(memcpy string.h HAVE_MEMCPY)
-  if(NOT HAVE_MEMSET AND NOT HAVE_MEMCPY)
-    set(NEED_BSD_STRINGS 1)
-  endif()
-
-  # Check for types
-  check_type_size("unsigned char" UNSIGNED_CHAR)
-  check_type_size("unsigned short" UNSIGNED_SHORT)
-
-  # Check for compiler features
-  check_c_source_compiles("int main(void) { typedef struct undefined_structure *undef_struct_ptr;  undef_struct_ptr ptr = 0;  return ptr != 0; }"
-    INCOMPLETE_TYPES)
-  if(INCOMPLETE_TYPES)
-    message(STATUS "Compiler supports pointers to undefined structures.")
-  else()
-    set(INCOMPLETE_TYPES_BROKEN 1)
-    message(STATUS "Compiler does not support pointers to undefined structures.")
-  endif()
-
-  if(CMAKE_CROSSCOMPILING)
-    set(RIGHT_SHIFT_IS_UNSIGNED 0)
-  else()
-    include(CheckCSourceRuns)
-    check_c_source_runs("
-      #include <stdio.h>
-      #include <stdlib.h>
-      int is_shifting_signed (long arg) {
-        long res = arg >> 4;
-        if (res == -0x7F7E80CL)
-          return 1; /* right shift is signed */
-        /* see if unsigned-shift hack will fix it. */
-        /* we can't just test exact value since it depends on width of long... */
-        res |= (~0L) << (32-4);
-        if (res == -0x7F7E80CL)
-          return 0; /* right shift is unsigned */
-        printf(\"Right shift isn't acting as I expect it to.\\\\n\");
-        printf(\"I fear the JPEG software will not work at all.\\\\n\\\\n\");
-        return 0; /* try it with unsigned anyway */
-      }
-      int main (void) {
-        exit(is_shifting_signed(-0x7F7E80B1L));
-      }" RIGHT_SHIFT_IS_UNSIGNED)
-  endif()
-
-  if(CMAKE_CROSSCOMPILING)
-    set(__CHAR_UNSIGNED__ 0)
-  else()
-    check_c_source_runs("int main(void) { return ((char) -1 < 0); }"
-      __CHAR_UNSIGNED__)
-  endif()
-endif()
-
-if(MSVC)
-  set(INLINE_OPTIONS "__inline;inline")
-else()
-  set(INLINE_OPTIONS "__inline__;inline")
-endif()
-option(FORCE_INLINE "Force function inlining" TRUE)
-boolean_number(FORCE_INLINE)
-if(FORCE_INLINE)
-  if(MSVC)
-    list(INSERT INLINE_OPTIONS 0 "__forceinline")
-  else()
-    list(INSERT INLINE_OPTIONS 0 "inline __attribute__((always_inline))")
-    list(INSERT INLINE_OPTIONS 0 "__inline__ __attribute__((always_inline))")
-  endif()
-endif()
-foreach(inline ${INLINE_OPTIONS})
-  check_c_source_compiles("${inline} static int foo(void) { return 0; } int main(void) { return foo(); }"
-    INLINE_WORKS)
-  if(INLINE_WORKS)
-    set(INLINE ${inline})
-    break()
-  endif()
-endforeach()
-if(NOT INLINE_WORKS)
-  message(FATAL_ERROR "Could not determine how to inline functions.")
-endif()
-message(STATUS "INLINE = ${INLINE} (FORCE_INLINE = ${FORCE_INLINE})")
-
-if(UNIX AND NOT APPLE)
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map "VERS_1 { global: *; };")
-  set(CMAKE_REQUIRED_FLAGS
-    "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
-  check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSION_SCRIPT)
-  set(CMAKE_REQUIRED_FLAGS)
-  file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map)
-  if(HAVE_VERSION_SCRIPT)
-    message(STATUS "Linker supports GNU-style version scripts")
-    set(MAPFLAG "-Wl,--version-script,")
-    set(TJMAPFLAG "-Wl,--version-script,")
-  else()
-    message(STATUS "Linker does not support GNU-style version scripts")
-    if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-      # The Solaris linker doesn't like our version script for the libjpeg API
-      # library, but the version script for the TurboJPEG API library should
-      # still work.
-      file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map
-        "VERS_1 { global: foo;  local: *; }; VERS_2 { global: foo2; } VERS_1;")
-      set(CMAKE_REQUIRED_FLAGS "-Wl,-M,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
-      check_c_source_compiles("void foo() {} void foo2() {} int main(void) { return 0; }"
-        HAVE_MAPFILE)
-      set(CMAKE_REQUIRED_FLAGS)
-      file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map)
-      if(HAVE_MAPFILE)
-        message(STATUS "Linker supports mapfiles")
-        set(TJMAPFLAG "-Wl,-M,")
-      else()
-        message(STATUS "Linker does not support mapfiles")
-      endif()
-    endif()
-  endif()
-endif()
-
-# Generate files
-if(WIN32)
-  configure_file(win/jconfig.h.in jconfig.h)
-else()
-  configure_file(jconfig.h.in jconfig.h)
-endif()
-configure_file(jconfigint.h.in jconfigint.h)
-if(UNIX)
-  configure_file(libjpeg.map.in libjpeg.map)
-endif()
-
-# Include directories and compiler definitions
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
-
-
-###############################################################################
-# TARGETS
-###############################################################################
-
-set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
-  jcicc.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c
-  jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c
-  jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdicc.c jdinput.c
-  jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c
-  jdtrans.c jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c
-  jidctint.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
-
-if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
-  set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
-endif()
-
-if(WITH_ARITH_ENC)
-  set(JPEG_SOURCES ${JPEG_SOURCES} jcarith.c)
-endif()
-
-if(WITH_ARITH_DEC)
-  set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
-endif()
-
-if(WITH_SIMD)
-  add_subdirectory(simd)
-elseif(NOT WITH_12BIT)
-  message(STATUS "SIMD extensions: None (WITH_SIMD = ${WITH_SIMD})")
-endif()
-if(WITH_SIMD)
-  message(STATUS "SIMD extensions: ${CPU_TYPE} (WITH_SIMD = ${WITH_SIMD})")
-  if(MSVC_IDE)
-    set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
-  endif()
-else()
-  add_library(simd OBJECT jsimd_none.c)
-endif()
-
-if(WITH_JAVA)
-  add_subdirectory(java)
-endif()
-
-if(ENABLE_SHARED)
-  add_subdirectory(sharedlib)
-endif()
-
-if(ENABLE_STATIC)
-  add_library(jpeg-static STATIC ${JPEG_SOURCES} $<TARGET_OBJECTS:simd>
-    ${SIMD_OBJS})
-  if(NOT MSVC)
-    set_target_properties(jpeg-static PROPERTIES OUTPUT_NAME jpeg)
-  endif()
-endif()
-
-if(WITH_TURBOJPEG)
-  if(ENABLE_SHARED)
-    set(TURBOJPEG_SOURCES ${JPEG_SOURCES} $<TARGET_OBJECTS:simd> ${SIMD_OBJS}
-      turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c rdbmp.c rdppm.c
-      wrbmp.c wrppm.c)
-    set(TJMAPFILE ${CMAKE_CURRENT_SOURCE_DIR}/turbojpeg-mapfile)
-    if(WITH_JAVA)
-      set(TURBOJPEG_SOURCES ${TURBOJPEG_SOURCES} turbojpeg-jni.c)
-      include_directories(${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
-      set(TJMAPFILE ${CMAKE_CURRENT_SOURCE_DIR}/turbojpeg-mapfile.jni)
-    endif()
-    add_library(turbojpeg SHARED ${TURBOJPEG_SOURCES})
-    set_property(TARGET turbojpeg PROPERTY COMPILE_FLAGS
-      "-DBMP_SUPPORTED -DPPM_SUPPORTED")
-    if(WIN32)
-      set_target_properties(turbojpeg PROPERTIES DEFINE_SYMBOL DLLDEFINE)
-    endif()
-    if(MINGW)
-      set_target_properties(turbojpeg PROPERTIES LINK_FLAGS -Wl,--kill-at)
-    endif()
-    if(APPLE)
-      if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
-        set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
-      endif()
-      set_target_properties(turbojpeg PROPERTIES MACOSX_RPATH 1)
-    endif()
-    set_target_properties(turbojpeg PROPERTIES
-      SOVERSION ${TURBOJPEG_SO_MAJOR_VERSION} VERSION ${TURBOJPEG_SO_VERSION})
-    if(TJMAPFLAG)
-      set_target_properties(turbojpeg PROPERTIES
-        LINK_FLAGS "${TJMAPFLAG}${TJMAPFILE}")
-    endif()
-
-    add_executable(tjunittest tjunittest.c tjutil.c md5/md5.c md5/md5hl.c)
-    target_link_libraries(tjunittest turbojpeg)
-
-    add_executable(tjbench tjbench.c tjutil.c)
-    target_link_libraries(tjbench turbojpeg)
-    if(UNIX)
-      target_link_libraries(tjbench m)
-    endif()
-
-    add_executable(tjexample tjexample.c)
-    target_link_libraries(tjexample turbojpeg)
-  endif()
-
-  if(ENABLE_STATIC)
-    add_library(turbojpeg-static STATIC ${JPEG_SOURCES} $<TARGET_OBJECTS:simd>
-      ${SIMD_OBJS} turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c rdbmp.c
-      rdppm.c wrbmp.c wrppm.c)
-    set_property(TARGET turbojpeg-static PROPERTY COMPILE_FLAGS
-      "-DBMP_SUPPORTED -DPPM_SUPPORTED")
-    if(NOT MSVC)
-      set_target_properties(turbojpeg-static PROPERTIES OUTPUT_NAME turbojpeg)
-    endif()
-
-    add_executable(tjunittest-static tjunittest.c tjutil.c md5/md5.c
-      md5/md5hl.c)
-    target_link_libraries(tjunittest-static turbojpeg-static)
-
-    add_executable(tjbench-static tjbench.c tjutil.c)
-    target_link_libraries(tjbench-static turbojpeg-static)
-    if(UNIX)
-      target_link_libraries(tjbench-static m)
-    endif()
-  endif()
-endif()
-
-if(WIN32)
-  set(USE_SETMODE "-DUSE_SETMODE")
-endif()
-if(WITH_12BIT)
-  set(COMPILE_FLAGS "-DGIF_SUPPORTED -DPPM_SUPPORTED ${USE_SETMODE}")
-else()
-  set(COMPILE_FLAGS "-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
-  set(CJPEG_BMP_SOURCES rdbmp.c rdtarga.c)
-  set(DJPEG_BMP_SOURCES wrbmp.c wrtarga.c)
-endif()
-
-if(ENABLE_STATIC)
-  add_executable(cjpeg-static cjpeg.c cdjpeg.c rdgif.c rdppm.c rdswitch.c
-    ${CJPEG_BMP_SOURCES})
-  set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
-  target_link_libraries(cjpeg-static jpeg-static)
-
-  add_executable(djpeg-static djpeg.c cdjpeg.c rdcolmap.c rdswitch.c wrgif.c
-    wrppm.c ${DJPEG_BMP_SOURCES})
-  set_property(TARGET djpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
-  target_link_libraries(djpeg-static jpeg-static)
-
-  add_executable(jpegtran-static jpegtran.c cdjpeg.c rdswitch.c transupp.c)
-  target_link_libraries(jpegtran-static jpeg-static)
-  set_property(TARGET jpegtran-static PROPERTY COMPILE_FLAGS "${USE_SETMODE}")
-endif()
-
-add_executable(rdjpgcom rdjpgcom.c)
-
-add_executable(wrjpgcom wrjpgcom.c)
-
-
-###############################################################################
-# TESTS
-###############################################################################
-
-add_subdirectory(md5)
-
-if(MSVC_IDE)
-  set(OBJDIR "\${CTEST_CONFIGURATION_TYPE}/")
-else()
-  set(OBJDIR "")
-endif()
-
-enable_testing()
-
-if(WITH_12BIT)
-  set(TESTORIG testorig12.jpg)
-  set(MD5_JPEG_RGB_ISLOW 9d7369207c520d37f2c1cbfcb82b2964)
-  set(MD5_JPEG_RGB_ISLOW2 a00bd20d8ae49684640ef7177d2e0b64)
-  set(MD5_PPM_RGB_ISLOW f3301d2219783b8b3d942b7239fa50c0)
-  set(MD5_JPEG_422_IFAST_OPT 7322e3bd2f127f7de4b40d4480ce60e4)
-  set(MD5_PPM_422_IFAST 79807fa552899e66a04708f533e16950)
-  set(MD5_PPM_422M_IFAST 07737bfe8a7c1c87aaa393a0098d16b0)
-  set(MD5_JPEG_420_IFAST_Q100_PROG a1da220b5604081863a504297ed59e55)
-  set(MD5_PPM_420_Q100_IFAST 1b3730122709f53d007255e8dfd3305e)
-  set(MD5_PPM_420M_Q100_IFAST 980a1a3c5bf9510022869d30b7d26566)
-  set(MD5_JPEG_GRAY_ISLOW 235c90707b16e2e069f37c888b2636d9)
-  set(MD5_PPM_GRAY_ISLOW 7213c10af507ad467da5578ca5ee1fca)
-  set(MD5_PPM_GRAY_ISLOW_RGB e96ee81c30a6ed422d466338bd3de65d)
-  set(MD5_JPEG_420S_IFAST_OPT 7af8e60be4d9c227ec63ac9b6630855e)
-
-  set(MD5_JPEG_3x2_FLOAT_PROG_SSE a8c17daf77b457725ec929e215b603f8)
-  set(MD5_PPM_3x2_FLOAT_SSE 42876ab9e5c2f76a87d08db5fbd57956)
-  set(MD5_JPEG_3x2_FLOAT_PROG_32BIT a8c17daf77b457725ec929e215b603f8)
-  set(MD5_PPM_3x2_FLOAT_32BIT ${MD5_PPM_3x2_FLOAT_SSE})
-  set(MD5_JPEG_3x2_FLOAT_PROG_64BIT ${MD5_JPEG_3x2_FLOAT_PROG_32BIT})
-  set(MD5_PPM_3x2_FLOAT_64BIT ${MD5_PPM_3x2_FLOAT_SSE})
-  set(MD5_JPEG_3x2_FLOAT_PROG_387 bc6dbbefac2872f6b9d6c4a0ae60c3c0)
-  set(MD5_PPM_3x2_FLOAT_387 bcc5723c61560463ac60f772e742d092)
-  set(MD5_JPEG_3x2_FLOAT_PROG_MSVC e27840755870fa849872e58aa0cd1400)
-  set(MD5_PPM_3x2_FLOAT_MSVC 6c2880b83bb1aa41dfe330e7a9768690)
-
-  set(MD5_JPEG_3x2_IFAST_PROG 1396cc2b7185cfe943d408c9d305339e)
-  set(MD5_PPM_3x2_IFAST 3975985ef6eeb0a2cdc58daa651ccc00)
-  set(MD5_PPM_420M_ISLOW_2_1 4ca6be2a6f326ff9eaab63e70a8259c0)
-  set(MD5_PPM_420M_ISLOW_15_8 12aa9f9534c1b3d7ba047322226365eb)
-  set(MD5_PPM_420M_ISLOW_13_8 f7e22817c7b25e1393e4ec101e9d4e96)
-  set(MD5_PPM_420M_ISLOW_11_8 800a16f9f4dc9b293197bfe11be10a82)
-  set(MD5_PPM_420M_ISLOW_9_8 06b7a92a9bc69f4dc36ec40f1937d55c)
-  set(MD5_PPM_420M_ISLOW_7_8 3ec444a14a4ab4eab88ffc49c48eca43)
-  set(MD5_PPM_420M_ISLOW_3_4 3e726b7ea872445b19437d1c1d4f0d93)
-  set(MD5_PPM_420M_ISLOW_5_8 a8a771abdc94301d20ffac119b2caccd)
-  set(MD5_PPM_420M_ISLOW_1_2 b419124dd5568b085787234866102866)
-  set(MD5_PPM_420M_ISLOW_3_8 343d19015531b7bbe746124127244fa8)
-  set(MD5_PPM_420M_ISLOW_1_4 35fd59d866e44659edfa3c18db2a3edb)
-  set(MD5_PPM_420M_ISLOW_1_8 ccaed48ac0aedefda5d4abe4013f4ad7)
-  set(MD5_PPM_420_ISLOW_SKIP15_31 86664cd9dc956536409e44e244d20a97)
-  set(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 452a21656115a163029cfba5c04fa76a)
-  set(MD5_PPM_444_ISLOW_SKIP1_6 ef63901f71ef7a75cd78253fc0914f84)
-  set(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 15b173fb5872d9575572fbcc1b05956f)
-  set(MD5_JPEG_CROP cdb35ff4b4519392690ea040c56ea99c)
-else()
-  set(TESTORIG testorig.jpg)
-  set(MD5_JPEG_RGB_ISLOW 1d44a406f61da743b5fd31c0a9abdca3)
-  set(MD5_JPEG_RGB_ISLOW2 31d121e57b6c2934c890a7fc7763bcd4)
-  set(MD5_PPM_RGB_ISLOW 00a257f5393fef8821f2b88ac7421291)
-  set(MD5_BMP_RGB_ISLOW_565 f07d2e75073e4bb10f6c6f4d36e2e3be)
-  set(MD5_BMP_RGB_ISLOW_565D 4cfa0928ef3e6bb626d7728c924cfda4)
-  set(MD5_JPEG_422_IFAST_OPT 2540287b79d913f91665e660303ab2c8)
-  set(MD5_PPM_422_IFAST 35bd6b3f833bad23de82acea847129fa)
-  set(MD5_PPM_422M_IFAST 8dbc65323d62cca7c91ba02dd1cfa81d)
-  set(MD5_BMP_422M_IFAST_565 3294bd4d9a1f2b3d08ea6020d0db7065)
-  set(MD5_BMP_422M_IFAST_565D da98c9c7b6039511be4a79a878a9abc1)
-  set(MD5_JPEG_420_IFAST_Q100_PROG 990cbe0329c882420a2094da7e5adade)
-  set(MD5_PPM_420_Q100_IFAST 5a732542015c278ff43635e473a8a294)
-  set(MD5_PPM_420M_Q100_IFAST ff692ee9323a3b424894862557c092f1)
-  set(MD5_JPEG_GRAY_ISLOW 72b51f894b8f4a10b3ee3066770aa38d)
-  set(MD5_PPM_GRAY_ISLOW 8d3596c56eace32f205deccc229aa5ed)
-  set(MD5_PPM_GRAY_ISLOW_RGB 116424ac07b79e5e801f00508eab48ec)
-  set(MD5_BMP_GRAY_ISLOW_565 12f78118e56a2f48b966f792fedf23cc)
-  set(MD5_BMP_GRAY_ISLOW_565D bdbbd616441a24354c98553df5dc82db)
-  set(MD5_JPEG_420S_IFAST_OPT 388708217ac46273ca33086b22827ed8)
-
-  set(MD5_JPEG_3x2_FLOAT_PROG_SSE 343e3f8caf8af5986ebaf0bdc13b5c71)
-  set(MD5_PPM_3x2_FLOAT_SSE 1a75f36e5904d6fc3a85a43da9ad89bb)
-  set(MD5_JPEG_3x2_FLOAT_PROG_32BIT 9bca803d2042bd1eb03819e2bf92b3e5)
-  set(MD5_PPM_3x2_FLOAT_32BIT f6bfab038438ed8f5522fbd33595dcdc)
-  set(MD5_JPEG_3x2_FLOAT_PROG_64BIT ${MD5_JPEG_3x2_FLOAT_PROG_32BIT})
-  set(MD5_PPM_3x2_FLOAT_64BIT 0e917a34193ef976b679a6b069b1be26)
-  set(MD5_JPEG_3x2_FLOAT_PROG_387 1657664a410e0822c924b54f6f65e6e9)
-  set(MD5_PPM_3x2_FLOAT_387 cb0a1f027f3d2917c902b5640214e025)
-  set(MD5_JPEG_3x2_FLOAT_PROG_MSVC 7999ce9cd0ee9b6c7043b7351ab7639d)
-  set(MD5_PPM_3x2_FLOAT_MSVC 28cdc448a6b75e97892f0e0f8d4b21f3)
-
-  set(MD5_JPEG_3x2_IFAST_PROG 1ee5d2c1a77f2da495f993c8c7cceca5)
-  set(MD5_PPM_3x2_IFAST fd283664b3b49127984af0a7f118fccd)
-  set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1)
-  set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617)
-  set(MD5_PPM_420M_IFAST_ARI 72b59a99bcf1de24c5b27d151bde2437)
-  set(MD5_JPEG_420_ISLOW 9a68f56bc76e466aa7e52f415d0f4a5f)
-  set(MD5_PPM_420M_ISLOW_2_1 9f9de8c0612f8d06869b960b05abf9c9)
-  set(MD5_PPM_420M_ISLOW_15_8 b6875bc070720b899566cc06459b63b7)
-  set(MD5_PPM_420M_ISLOW_13_8 bc3452573c8152f6ae552939ee19f82f)
-  set(MD5_PPM_420M_ISLOW_11_8 d8cc73c0aaacd4556569b59437ba00a5)
-  set(MD5_PPM_420M_ISLOW_9_8 d25e61bc7eac0002f5b393aa223747b6)
-  set(MD5_PPM_420M_ISLOW_7_8 ddb564b7c74a09494016d6cd7502a946)
-  set(MD5_PPM_420M_ISLOW_3_4 8ed8e68808c3fbc4ea764fc9d2968646)
-  set(MD5_PPM_420M_ISLOW_5_8 a3363274999da2366a024efae6d16c9b)
-  set(MD5_PPM_420M_ISLOW_1_2 e692a315cea26b988c8e8b29a5dbcd81)
-  set(MD5_PPM_420M_ISLOW_3_8 79eca9175652ced755155c90e785a996)
-  set(MD5_PPM_420M_ISLOW_1_4 79cd778f8bf1a117690052cacdd54eca)
-  set(MD5_PPM_420M_ISLOW_1_8 391b3d4aca640c8567d6f8745eb2142f)
-  set(MD5_BMP_420_ISLOW_256 4980185e3776e89bd931736e1cddeee6)
-  set(MD5_BMP_420_ISLOW_565 bf9d13e16c4923b92e1faa604d7922cb)
-  set(MD5_BMP_420_ISLOW_565D 6bde71526acc44bcff76f696df8638d2)
-  set(MD5_BMP_420M_ISLOW_565 8dc0185245353cfa32ad97027342216f)
-  set(MD5_BMP_420M_ISLOW_565D ce034037d212bc403330df6f915c161b)
-  set(MD5_PPM_420_ISLOW_SKIP15_31 c4c65c1e43d7275cd50328a61e6534f0)
-  set(MD5_PPM_420_ISLOW_ARI_SKIP16_139 087c6b123db16ac00cb88c5b590bb74a)
-  set(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71 26eb36ccc7d1f0cb80cdabb0ac8b5d99)
-  set(MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4 886c6775af22370257122f8b16207e6d)
-  set(MD5_PPM_444_ISLOW_SKIP1_6 5606f86874cf26b8fcee1117a0a436a6)
-  set(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13 db87dc7ce26bcdc7a6b56239ce2b9d6c)
-  set(MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0 cb57b32bd6d03e35432362f7bf184b6d)
-  set(MD5_JPEG_CROP b4197f377e621c4e9b1d20471432610d)
-endif()
-
-if(WITH_JAVA)
-  add_test(TJUnitTest
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest)
-  add_test(TJUnitTest-yuv
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest -yuv)
-  add_test(TJUnitTest-yuv-nopad
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest -yuv -noyuvpad)
-  add_test(TJUnitTest-bi
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest -bi)
-  add_test(TJUnitTest-bi-yuv
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest -bi -yuv)
-  add_test(TJUnitTest-bi-yuv-nopad
-    ${Java_JAVA_EXECUTABLE} ${JAVAARGS} -cp java/turbojpeg.jar
-      -Djava.library.path=${CMAKE_CURRENT_BINARY_DIR}/${OBJDIR}
-      TJUnitTest -bi -yuv -noyuvpad)
-endif()
-
-set(TEST_LIBTYPES "")
-if(ENABLE_SHARED)
-  set(TEST_LIBTYPES ${TEST_LIBTYPES} shared)
-endif()
-if(ENABLE_STATIC)
-  set(TEST_LIBTYPES ${TEST_LIBTYPES} static)
-endif()
-
-set(TESTIMAGES ${CMAKE_CURRENT_SOURCE_DIR}/testimages)
-set(MD5CMP ${CMAKE_CURRENT_BINARY_DIR}/md5/md5cmp)
-if(CMAKE_CROSSCOMPILING)
-  file(RELATIVE_PATH TESTIMAGES ${CMAKE_CURRENT_BINARY_DIR} ${TESTIMAGES})
-  file(RELATIVE_PATH MD5CMP ${CMAKE_CURRENT_BINARY_DIR} ${MD5CMP})
-endif()
-
-# The output of the floating point DCT/IDCT algorithms differs depending on the
-# type of floating point math used, so the FLOATTEST CMake variable must be
-# set in order to tell the testing system which floating point results it
-# should expect:
-#
-# sse = validate against the expected results from the libjpeg-turbo SSE SIMD
-#       extensions
-# 32bit = validate against the expected results from the C code when running on
-#         a 32-bit FPU (or when SSE is being used for floating point math,
-#         which is generally the default with x86-64 compilers)
-# 64bit = validate against the expected results from the C code when running
-#         on a 64-bit FPU
-# 387 = validate against the expected results from the C code when the 387 FPU
-#       is being used for floating point math (which is generally the default
-#       with x86 compilers)
-# msvc = validate against the expected results from the C code when compiled
-#        with a 32-bit version of Visual C++
-
-if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386")
-  if(WITH_SIMD)
-    set(DEFAULT_FLOATTEST sse)
-  elseif(CPU_TYPE STREQUAL "x86_64")
-    set(DEFAULT_FLOATTEST 32bit)
-  elseif(CPU_TYPE STREQUAL "i386" AND MSVC)
-    set(DEFAULT_FLOATTEST msvc)
-  endif()
-else()
-  if(BITS EQUAL 64)
-    set(DEFAULT_FLOATTEST 64bit)
-  elseif(BITS EQUAL 32)
-    set(DEFAULT_FLOATTEST 32bit)
-  endif()
-endif()
-
-# This causes FLOATTEST to reset to the default value if WITH_SIMD has
-# changed.
-if(DEFINED WITH_SIMD_INT AND NOT WITH_SIMD EQUAL WITH_SIMD_INT)
-  set(FORCE_FLOATTEST "FORCE")
-endif()
-set(WITH_SIMD_INT ${WITH_SIMD} CACHE INTERNAL "")
-set(FLOATTEST ${DEFAULT_FLOATTEST} CACHE STRING
-  "The type of floating point math used by the floating point DCT/IDCT algorithms.  This tells the testing system which numerical results it should expect from those tests.  [sse = libjpeg-turbo x86/x86-64 SIMD extensions, 32bit = generic 32-bit FPU or SSE, 64bit = generic 64-bit FPU, 387 = 387 FPU, msvc = 32-bit Visual Studio] (default = ${DEFAULT_FLOATTEST})"
-  ${FORCE_FLOATTEST})
-message(STATUS "FLOATTEST = ${FLOATTEST}")
-
-if(FLOATTEST)
-  string(TOUPPER ${FLOATTEST} FLOATTEST_UC)
-  string(TOLOWER ${FLOATTEST} FLOATTEST)
-  if(NOT FLOATTEST STREQUAL "sse" AND NOT FLOATTEST STREQUAL "32bit" AND
-    NOT FLOATTEST STREQUAL "64bit" AND NOT FLOATTEST STREQUAL "387" AND
-    NOT FLOATTEST STREQUAL "msvc")
-    message(FATAL_ERROR "\"${FLOATTEST}\" is not a valid value for FLOATTEST.")
-  endif()
-endif()
-
-foreach(libtype ${TEST_LIBTYPES})
-  if(libtype STREQUAL "static")
-    set(suffix -static)
-  endif()
-  if(WITH_TURBOJPEG)
-    add_test(tjunittest-${libtype} tjunittest${suffix})
-    add_test(tjunittest-${libtype}-alloc tjunittest${suffix} -alloc)
-    add_test(tjunittest-${libtype}-yuv tjunittest${suffix} -yuv)
-    add_test(tjunittest-${libtype}-yuv-alloc tjunittest${suffix} -yuv -alloc)
-    add_test(tjunittest-${libtype}-yuv-nopad tjunittest${suffix} -yuv -noyuvpad)
-    add_test(tjunittest-${libtype}-bmp tjunittest${suffix} -bmp)
-
-    set(MD5_PPM_GRAY_TILE 89d3ca21213d9d864b50b4e4e7de4ca6)
-    set(MD5_PPM_420_8x8_TILE 847fceab15c5b7b911cb986cf0f71de3)
-    set(MD5_PPM_420_16x16_TILE ca45552a93687e078f7137cc4126a7b0)
-    set(MD5_PPM_420_32x32_TILE d8676f1d6b68df358353bba9844f4a00)
-    set(MD5_PPM_420_64x64_TILE 4e4c1a3d7ea4bace4f868bcbe83b7050)
-    set(MD5_PPM_420_128x128_TILE f24c3429c52265832beab9df72a0ceae)
-    set(MD5_PPM_420M_8x8_TILE bc25320e1f4c31ce2e610e43e9fd173c)
-    set(MD5_PPM_420M_TILE 75ffdf14602258c5c189522af57fa605)
-    set(MD5_PPM_422_8x8_TILE d83dacd9fc73b0a6f10c09acad64eb1e)
-    set(MD5_PPM_422_16x16_TILE 35077fb610d72dd743b1eb0cbcfe10fb)
-    set(MD5_PPM_422_32x32_TILE e6902ed8a449ecc0f0d6f2bf945f65f7)
-    set(MD5_PPM_422_64x64_TILE 2b4502a8f316cedbde1da7bce3d2231e)
-    set(MD5_PPM_422_128x128_TILE f0b5617d578f5e13c8eee215d64d4877)
-    set(MD5_PPM_422M_8x8_TILE 828941d7f41cd6283abd6beffb7fd51d)
-    set(MD5_PPM_422M_TILE e877ae1324c4a280b95376f7f018172f)
-    set(MD5_PPM_444_TILE 7964e41e67cfb8d0a587c0aa4798f9c3)
-
-    # Test compressing from/decompressing to an arbitrary subregion of a larger
-    # image buffer
-    add_test(tjbench-${libtype}-tile-cp
-      ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm
-        testout_tile.ppm)
-    add_test(tjbench-${libtype}-tile
-      tjbench${suffix} testout_tile.ppm 95 -rgb -quiet -tile -benchtime 0.01
-        -warmup 0)
-    set_tests_properties(tjbench-${libtype}-tile
-      PROPERTIES DEPENDS tjbench-${libtype}-tile-cp)
-
-    foreach(tile 8 16 32 64 128)
-      add_test(tjbench-${libtype}-tile-gray-${tile}x${tile}-cmp
-        ${MD5CMP} ${MD5_PPM_GRAY_TILE}
-          testout_tile_GRAY_Q95_${tile}x${tile}.ppm)
-      foreach(subsamp 420 422)
-        add_test(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
-          ${MD5CMP} ${MD5_PPM_${subsamp}_${tile}x${tile}_TILE}
-            testout_tile_${subsamp}_Q95_${tile}x${tile}.ppm)
-      endforeach()
-      add_test(tjbench-${libtype}-tile-444-${tile}x${tile}-cmp
-        ${MD5CMP} ${MD5_PPM_444_TILE}
-          testout_tile_444_Q95_${tile}x${tile}.ppm)
-      foreach(subsamp gray 420 422 444)
-        set_tests_properties(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
-          PROPERTIES DEPENDS tjbench-${libtype}-tile)
-      endforeach()
-    endforeach()
-
-    add_test(tjbench-${libtype}-tilem-cp
-      ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm
-        testout_tilem.ppm)
-    add_test(tjbench-${libtype}-tilem
-      tjbench${suffix} testout_tilem.ppm 95 -rgb -fastupsample -quiet -tile
-        -benchtime 0.01 -warmup 0)
-    set_tests_properties(tjbench-${libtype}-tilem
-      PROPERTIES DEPENDS tjbench-${libtype}-tilem-cp)
-
-    add_test(tjbench-${libtype}-tile-420m-8x8-cmp
-      ${MD5CMP} ${MD5_PPM_420M_8x8_TILE} testout_tilem_420_Q95_8x8.ppm)
-    add_test(tjbench-${libtype}-tile-422m-8x8-cmp
-      ${MD5CMP} ${MD5_PPM_422M_8x8_TILE} testout_tilem_422_Q95_8x8.ppm)
-    foreach(tile 16 32 64 128)
-      foreach(subsamp 420 422)
-        add_test(tjbench-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp
-          ${MD5CMP} ${MD5_PPM_${subsamp}M_TILE}
-            testout_tilem_${subsamp}_Q95_${tile}x${tile}.ppm)
-      endforeach()
-    endforeach()
-    foreach(tile 8 16 32 64 128)
-      foreach(subsamp 420 422)
-        set_tests_properties(tjbench-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp
-          PROPERTIES DEPENDS tjbench-${libtype}-tilem)
-      endforeach()
-    endforeach()
-  endif()
-
-  # These tests are carefully crafted to provide full coverage of as many of
-  # the underlying algorithms as possible (including all of the
-  # SIMD-accelerated ones.)
-
-  macro(add_bittest PROG NAME ARGS OUTFILE INFILE MD5SUM)
-    add_test(${PROG}-${libtype}-${NAME}
-      ${PROG}${suffix} ${ARGS} -outfile ${OUTFILE} ${INFILE})
-    add_test(${PROG}-${libtype}-${NAME}-cmp
-      ${MD5CMP} ${MD5SUM} ${OUTFILE})
-    set_tests_properties(${PROG}-${libtype}-${NAME}-cmp PROPERTIES
-      DEPENDS ${PROG}-${libtype}-${NAME})
-    if(${ARGC} GREATER 6)
-      set(DEPENDS ${ARGN})
-      set_tests_properties(${PROG}-${libtype}-${NAME} PROPERTIES
-        DEPENDS ${DEPENDS})
-    endif()
-  endmacro()
-
-  # CC: null  SAMP: fullsize  FDCT: islow  ENT: huff
-  add_bittest(cjpeg rgb-islow "-rgb;-dct;int;-icc;${TESTIMAGES}/test1.icc"
-    testout_rgb_islow.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_RGB_ISLOW})
-
-  # CC: null  SAMP: fullsize  IDCT: islow  ENT: huff
-  add_bittest(djpeg rgb-islow "-dct;int;-ppm;-icc;testout_rgb_islow.icc"
-    testout_rgb_islow.ppm testout_rgb_islow.jpg
-    ${MD5_PPM_RGB_ISLOW} cjpeg-${libtype}-rgb-islow)
-
-  add_test(djpeg-${libtype}-rgb-islow-icc-cmp
-    ${MD5CMP} b06a39d730129122e85c1363ed1bbc9e testout_rgb_islow.icc)
-
-  add_bittest(jpegtran icc "-copy;all;-icc;${TESTIMAGES}/test2.icc"
-    testout_rgb_islow2.jpg testout_rgb_islow.jpg ${MD5_JPEG_RGB_ISLOW2})
-
-  if(NOT WITH_12BIT)
-    # CC: RGB->RGB565  SAMP: fullsize  IDCT: islow  ENT: huff
-    add_bittest(djpeg rgb-islow-565 "-dct;int;-rgb565;-dither;none;-bmp"
-      testout_rgb_islow_565.bmp testout_rgb_islow.jpg
-      ${MD5_BMP_RGB_ISLOW_565} cjpeg-${libtype}-rgb-islow)
-
-    # CC: RGB->RGB565 (dithered)  SAMP: fullsize  IDCT: islow  ENT: huff
-    add_bittest(djpeg rgb-islow-565D "-dct;int;-rgb565;-bmp"
-      testout_rgb_islow_565D.bmp testout_rgb_islow.jpg
-      ${MD5_BMP_RGB_ISLOW_565D} cjpeg-${libtype}-rgb-islow)
-  endif()
-
-  # CC: RGB->YCC  SAMP: fullsize/h2v1  FDCT: ifast  ENT: 2-pass huff
-  add_bittest(cjpeg 422-ifast-opt "-sample;2x1;-dct;fast;-opt"
-    testout_422_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_422_IFAST_OPT})
-
-  # CC: YCC->RGB  SAMP: fullsize/h2v1 fancy  IDCT: ifast  ENT: huff
-  add_bittest(djpeg 422-ifast "-dct;fast"
-    testout_422_ifast.ppm testout_422_ifast_opt.jpg
-    ${MD5_PPM_422_IFAST} cjpeg-${libtype}-422-ifast-opt)
-
-  # CC: YCC->RGB  SAMP: h2v1 merged  IDCT: ifast  ENT: huff
-  add_bittest(djpeg 422m-ifast "-dct;fast;-nosmooth"
-    testout_422m_ifast.ppm testout_422_ifast_opt.jpg
-    ${MD5_PPM_422M_IFAST} cjpeg-${libtype}-422-ifast-opt)
-
-  if(NOT WITH_12BIT)
-    # CC: YCC->RGB565  SAMP: h2v1 merged  IDCT: ifast  ENT: huff
-    add_bittest(djpeg 422m-ifast-565
-      "-dct;int;-nosmooth;-rgb565;-dither;none;-bmp"
-      testout_422m_ifast_565.bmp testout_422_ifast_opt.jpg
-      ${MD5_BMP_422M_IFAST_565} cjpeg-${libtype}-422-ifast-opt)
-
-    # CC: YCC->RGB565 (dithered)  SAMP: h2v1 merged  IDCT: ifast  ENT: huff
-    add_bittest(djpeg 422m-ifast-565D "-dct;int;-nosmooth;-rgb565;-bmp"
-      testout_422m_ifast_565D.bmp testout_422_ifast_opt.jpg
-      ${MD5_BMP_422M_IFAST_565D} cjpeg-${libtype}-422-ifast-opt)
-  endif()
-
-  # CC: RGB->YCC  SAMP: fullsize/h2v2  FDCT: ifast  ENT: prog huff
-  add_bittest(cjpeg 420-q100-ifast-prog
-    "-sample;2x2;-quality;100;-dct;fast;-prog"
-    testout_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_420_IFAST_Q100_PROG})
-
-  # CC: YCC->RGB  SAMP: fullsize/h2v2 fancy  IDCT: ifast  ENT: prog huff
-  add_bittest(djpeg 420-q100-ifast-prog "-dct;fast"
-    testout_420_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
-    ${MD5_PPM_420_Q100_IFAST} cjpeg-${libtype}-420-q100-ifast-prog)
-
-  # CC: YCC->RGB  SAMP: h2v2 merged  IDCT: ifast  ENT: prog huff
-  add_bittest(djpeg 420m-q100-ifast-prog "-dct;fast;-nosmooth"
-    testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
-    ${MD5_PPM_420M_Q100_IFAST} cjpeg-${libtype}-420-q100-ifast-prog)
-
-  # CC: RGB->Gray  SAMP: fullsize  FDCT: islow  ENT: huff
-  add_bittest(cjpeg gray-islow "-gray;-dct;int"
-    testout_gray_islow.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_GRAY_ISLOW})
-
-  # CC: Gray->Gray  SAMP: fullsize  IDCT: islow  ENT: huff
-  add_bittest(djpeg gray-islow "-dct;int"
-    testout_gray_islow.ppm testout_gray_islow.jpg
-    ${MD5_PPM_GRAY_ISLOW} cjpeg-${libtype}-gray-islow)
-
-  # CC: Gray->RGB  SAMP: fullsize  IDCT: islow  ENT: huff
-  add_bittest(djpeg gray-islow-rgb "-dct;int;-rgb"
-    testout_gray_islow_rgb.ppm testout_gray_islow.jpg
-    ${MD5_PPM_GRAY_ISLOW_RGB} cjpeg-${libtype}-gray-islow)
-
-  if(NOT WITH_12BIT)
-    # CC: Gray->RGB565  SAMP: fullsize  IDCT: islow  ENT: huff
-    add_bittest(djpeg gray-islow-565 "-dct;int;-rgb565;-dither;none;-bmp"
-      testout_gray_islow_565.bmp testout_gray_islow.jpg
-      ${MD5_BMP_GRAY_ISLOW_565} cjpeg-${libtype}-gray-islow)
-
-    # CC: Gray->RGB565 (dithered)  SAMP: fullsize  IDCT: islow  ENT: huff
-    add_bittest(djpeg gray-islow-565D "-dct;int;-rgb565;-bmp"
-      testout_gray_islow_565D.bmp testout_gray_islow.jpg
-      ${MD5_BMP_GRAY_ISLOW_565D} cjpeg-${libtype}-gray-islow)
-  endif()
-
-  # CC: RGB->YCC  SAMP: fullsize smooth/h2v2 smooth  FDCT: islow
-  # ENT: 2-pass huff
-  add_bittest(cjpeg 420s-ifast-opt "-sample;2x2;-smooth;1;-dct;int;-opt"
-    testout_420s_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_420S_IFAST_OPT})
-
-  if(FLOATTEST)
-    # CC: RGB->YCC  SAMP: fullsize/int  FDCT: float  ENT: prog huff
-    add_bittest(cjpeg 3x2-float-prog "-sample;3x2;-dct;float;-prog"
-      testout_3x2_float_prog.jpg ${TESTIMAGES}/testorig.ppm
-      ${MD5_JPEG_3x2_FLOAT_PROG_${FLOATTEST_UC}})
-
-    # CC: YCC->RGB  SAMP: fullsize/int  IDCT: float  ENT: prog huff
-    add_bittest(djpeg 3x2-float-prog "-dct;float"
-      testout_3x2_float.ppm testout_3x2_float_prog.jpg
-      ${MD5_PPM_3x2_FLOAT_${FLOATTEST_UC}} cjpeg-${libtype}-3x2-float-prog)
-  endif()
-
-    # CC: RGB->YCC  SAMP: fullsize/int  FDCT: ifast  ENT: prog huff
-  add_bittest(cjpeg 3x2-ifast-prog "-sample;3x2;-dct;fast;-prog"
-    testout_3x2_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm
-    ${MD5_JPEG_3x2_IFAST_PROG})
-
-  # CC: YCC->RGB  SAMP: fullsize/int  IDCT: ifast  ENT: prog huff
-  add_bittest(djpeg 3x2-ifast-prog "-dct;fast"
-    testout_3x2_ifast.ppm testout_3x2_ifast_prog.jpg
-    ${MD5_PPM_3x2_IFAST} cjpeg-${libtype}-3x2-ifast-prog)
-
-  if(WITH_ARITH_ENC)
-    # CC: YCC->RGB  SAMP: fullsize/h2v2  FDCT: islow  ENT: arith
-    add_bittest(cjpeg 420-islow-ari "-dct;int;-arithmetic"
-      testout_420_islow_ari.jpg ${TESTIMAGES}/testorig.ppm
-      ${MD5_JPEG_420_ISLOW_ARI})
-
-    add_bittest(jpegtran 420-islow-ari "-arithmetic"
-      testout_420_islow_ari2.jpg ${TESTIMAGES}/testimgint.jpg
-      ${MD5_JPEG_420_ISLOW_ARI})
-
-    # CC: YCC->RGB  SAMP: fullsize  FDCT: islow  ENT: prog arith
-    add_bittest(cjpeg 444-islow-progari
-      "-sample;1x1;-dct;int;-prog;-arithmetic"
-      testout_444_islow_progari.jpg ${TESTIMAGES}/testorig.ppm
-      ${MD5_JPEG_444_ISLOW_PROGARI})
-  endif()
-
-  if(WITH_ARITH_DEC)
-    # CC: RGB->YCC  SAMP: h2v2 merged  IDCT: ifast  ENT: arith
-    add_bittest(djpeg 420m-ifast-ari "-fast;-ppm"
-      testout_420m_ifast_ari.ppm ${TESTIMAGES}/testimgari.jpg
-      ${MD5_PPM_420M_IFAST_ARI})
-
-    add_bittest(jpegtran 420-islow ""
-      testout_420_islow.jpg ${TESTIMAGES}/testimgari.jpg
-      ${MD5_JPEG_420_ISLOW})
-  endif()
-
-  # 2/1--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 16x16 islow  ENT: huff
-  # 15/8--  CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 15x15 islow  ENT: huff
-  # 13/8--  CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 13x13 islow  ENT: huff
-  # 11/8--  CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 11x11 islow  ENT: huff
-  # 9/8--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 9x9 islow  ENT: huff
-  # 7/8--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 7x7 islow/14x14 islow
-  #         ENT: huff
-  # 3/4--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 6x6 islow/12x12 islow
-  #         ENT: huff
-  # 5/8--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 5x5 islow/10x10 islow
-  #         ENT: huff
-  # 1/2--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 4x4 islow/8x8 islow
-  #         ENT: huff
-  # 3/8--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 3x3 islow/6x6 islow
-  #         ENT: huff
-  # 1/4--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 2x2 islow/4x4 islow
-  #         ENT: huff
-  # 1/8--   CC: YCC->RGB  SAMP: h2v2 merged  IDCT: 1x1 islow/2x2 islow
-  #         ENT: huff
-  foreach(scale 2_1 15_8 13_8 11_8 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8)
-    string(REGEX REPLACE "_" "/" scalearg ${scale})
-    add_bittest(djpeg 420m-islow-${scale}
-      "-dct;int;-scale;${scalearg};-nosmooth;-ppm"
-      testout_420m_islow_${scale}.ppm ${TESTIMAGES}/${TESTORIG}
-      ${MD5_PPM_420M_ISLOW_${scale}})
-  endforeach()
-
-  if(NOT WITH_12BIT)
-    # CC: YCC->RGB (dithered)  SAMP: h2v2 fancy  IDCT: islow  ENT: huff
-    add_bittest(djpeg 420-islow-256 "-dct;int;-colors;256;-bmp"
-      testout_420_islow_256.bmp ${TESTIMAGES}/${TESTORIG}
-      ${MD5_BMP_420_ISLOW_256})
-
-    # CC: YCC->RGB565  SAMP: h2v2 fancy  IDCT: islow  ENT: huff
-    add_bittest(djpeg 420-islow-565 "-dct;int;-rgb565;-dither;none;-bmp"
-      testout_420_islow_565.bmp ${TESTIMAGES}/${TESTORIG}
-      ${MD5_BMP_420_ISLOW_565})
-
-    # CC: YCC->RGB565 (dithered)  SAMP: h2v2 fancy  IDCT: islow  ENT: huff
-    add_bittest(djpeg 420-islow-565D "-dct;int;-rgb565;-bmp"
-      testout_420_islow_565D.bmp ${TESTIMAGES}/${TESTORIG}
-      ${MD5_BMP_420_ISLOW_565D})
-
-    # CC: YCC->RGB565  SAMP: h2v2 merged  IDCT: islow  ENT: huff
-    add_bittest(djpeg 420m-islow-565
-      "-dct;int;-nosmooth;-rgb565;-dither;none;-bmp"
-      testout_420m_islow_565.bmp ${TESTIMAGES}/${TESTORIG}
-      ${MD5_BMP_420M_ISLOW_565})
-
-    # CC: YCC->RGB565 (dithered)  SAMP: h2v2 merged  IDCT: islow  ENT: huff
-    add_bittest(djpeg 420m-islow-565D "-dct;int;-nosmooth;-rgb565;-bmp"
-      testout_420m_islow_565D.bmp ${TESTIMAGES}/${TESTORIG}
-      ${MD5_BMP_420M_ISLOW_565D})
-  endif()
-
-  # Partial decode tests.  These tests are designed to cover all of the
-  # possible code paths in jpeg_skip_scanlines().
-
-  # Context rows: Yes  Intra-iMCU row: Yes  iMCU row prefetch: No   ENT: huff
-  add_bittest(djpeg 420-islow-skip15_31 "-dct;int;-skip;15,31;-ppm"
-    testout_420_islow_skip15,31.ppm ${TESTIMAGES}/${TESTORIG}
-    ${MD5_PPM_420_ISLOW_SKIP15_31})
-
-  # Context rows: Yes  Intra-iMCU row: No   iMCU row prefetch: Yes  ENT: arith
-  if(WITH_ARITH_DEC)
-    add_bittest(djpeg 420-islow-ari-skip16_139 "-dct;int;-skip;16,139;-ppm"
-      testout_420_islow_ari_skip16,139.ppm ${TESTIMAGES}/testimgari.jpg
-      ${MD5_PPM_420_ISLOW_ARI_SKIP16_139})
-  endif()
-
-  # Context rows: Yes  Intra-iMCU row: No   iMCU row prefetch: No   ENT: prog huff
-  add_test(cjpeg-${libtype}-420-islow-prog
-    cjpeg${suffix} -dct int -prog
-      -outfile testout_420_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
-  add_bittest(djpeg 420-islow-prog-crop62x62_71_71
-    "-dct;int;-crop;62x62+71+71;-ppm"
-    testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg
-    ${MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71} cjpeg-${libtype}-420-islow-prog)
-
-  # Context rows: Yes  Intra-iMCU row: No   iMCU row prefetch: No   ENT: arith
-  if(WITH_ARITH_DEC)
-    add_bittest(djpeg 420-islow-ari-crop53x53_4_4
-      "-dct;int;-crop;53x53+4+4;-ppm"
-      testout_420_islow_ari_crop53x53,4,4.ppm ${TESTIMAGES}/testimgari.jpg
-      ${MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4})
-  endif()
-
-  # Context rows: No   Intra-iMCU row: Yes  ENT: huff
-  add_test(cjpeg-${libtype}-444-islow
-    cjpeg${suffix} -dct int -sample 1x1
-      -outfile testout_444_islow.jpg ${TESTIMAGES}/testorig.ppm)
-  add_bittest(djpeg 444-islow-skip1_6 "-dct;int;-skip;1,6;-ppm"
-    testout_444_islow_skip1,6.ppm testout_444_islow.jpg
-    ${MD5_PPM_444_ISLOW_SKIP1_6} cjpeg-${libtype}-444-islow)
-
-  # Context rows: No   Intra-iMCU row: No   ENT: prog huff
-  add_test(cjpeg-${libtype}-444-islow-prog
-    cjpeg${suffix} -dct int -prog -sample 1x1
-      -outfile testout_444_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
-  add_bittest(djpeg 444-islow-prog-crop98x98_13_13
-    "-dct;int;-crop;98x98+13+13;-ppm"
-    testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg
-    ${MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13} cjpeg-${libtype}-444-islow-prog)
-
-  # Context rows: No   Intra-iMCU row: No   ENT: arith
-  if(WITH_ARITH_ENC)
-    add_test(cjpeg-${libtype}-444-islow-ari
-      cjpeg${suffix} -dct int -arithmetic -sample 1x1
-        -outfile testout_444_islow_ari.jpg ${TESTIMAGES}/testorig.ppm)
-    if(WITH_ARITH_DEC)
-      add_bittest(djpeg 444-islow-ari-crop37x37_0_0
-        "-dct;int;-crop;37x37+0+0;-ppm"
-        testout_444_islow_ari_crop37x37,0,0.ppm testout_444_islow_ari.jpg
-        ${MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0} cjpeg-${libtype}-444-islow-ari)
-    endif()
-  endif()
-
-  add_bittest(jpegtran crop "-crop;120x90+20+50;-transpose;-perfect"
-    testout_crop.jpg ${TESTIMAGES}/${TESTORIG}
-    ${MD5_JPEG_CROP})
-
-endforeach()
-
-add_custom_target(testclean COMMAND ${CMAKE_COMMAND} -P
-  ${CMAKE_CURRENT_SOURCE_DIR}/cmakescripts/testclean.cmake)
-
-if(WITH_TURBOJPEG)
-  configure_file(tjbenchtest.in tjbenchtest @ONLY)
-  configure_file(tjexampletest.in tjexampletest @ONLY)
-  if(WIN32)
-    set(BASH bash)
-  endif()
-  if(WITH_JAVA)
-    configure_file(tjbenchtest.java.in tjbenchtest.java @ONLY)
-    configure_file(tjexampletest.java.in tjexampletest.java @ONLY)
-    add_custom_target(tjtest
-      COMMAND echo tjbenchtest
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest
-      COMMAND echo tjbenchtest -alloc
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -alloc
-      COMMAND echo tjbenchtest -yuv
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv
-      COMMAND echo tjbenchtest -yuv -alloc
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv -alloc
-      COMMAND echo tjbenchtest -progressive
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -progressive
-      COMMAND echo tjexampletest
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest
-      COMMAND echo tjbenchtest.java
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java
-      COMMAND echo tjbenchtest.java -yuv
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java -yuv
-      COMMAND echo tjbenchtest.java -progressive
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java -progressive
-      COMMAND echo tjexampletest.java
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest.java
-      DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest
-        ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest.java
-        ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest)
-  else()
-    add_custom_target(tjtest
-      COMMAND echo tjbenchtest
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest
-      COMMAND echo tjbenchtest -alloc
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -alloc
-      COMMAND echo tjbenchtest -yuv
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv
-      COMMAND echo tjbenchtest -yuv -alloc
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest -yuv -alloc
-      COMMAND echo tjexampletest
-      COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/tjexampletest
-      DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/tjbenchtest)
-  endif()
-endif()
-
-
-###############################################################################
-# INSTALLATION
-###############################################################################
-
-if(WIN32)
-  set(EXE ".exe")
-endif()
-
-if(WITH_TURBOJPEG)
-  if(ENABLE_SHARED)
-    install(TARGETS turbojpeg tjbench
-      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-  endif()
-  if(ENABLE_STATIC)
-    install(TARGETS turbojpeg-static ARCHIVE
-      DESTINATION ${CMAKE_INSTALL_LIBDIR})
-    if(NOT ENABLE_SHARED)
-      install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tjbench-static${EXE}
-        DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME tjbench${EXE})
-    endif()
-  endif()
-  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/turbojpeg.h
-    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-endif()
-
-if(ENABLE_STATIC)
-  install(TARGETS jpeg-static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
-  if(NOT ENABLE_SHARED)
-    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/cjpeg-static${EXE}
-      DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME cjpeg${EXE})
-    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/djpeg-static${EXE}
-      DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME djpeg${EXE})
-    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/jpegtran-static${EXE}
-      DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME jpegtran${EXE})
-  endif()
-endif()
-
-install(TARGETS rdjpgcom wrjpgcom RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.ijg
-  ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/example.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/tjexample.c
-  ${CMAKE_CURRENT_SOURCE_DIR}/libjpeg.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/structure.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/usage.txt ${CMAKE_CURRENT_SOURCE_DIR}/wizard.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
-if(WITH_JAVA)
-  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/java/TJExample.java
-    DESTINATION ${CMAKE_INSTALL_DOCDIR})
-endif()
-
-if(UNIX OR MINGW)
-  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cjpeg.1
-    ${CMAKE_CURRENT_SOURCE_DIR}/djpeg.1 ${CMAKE_CURRENT_SOURCE_DIR}/jpegtran.1
-    ${CMAKE_CURRENT_SOURCE_DIR}/rdjpgcom.1
-    ${CMAKE_CURRENT_SOURCE_DIR}/wrjpgcom.1
-    DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libjpeg.pc
-    ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libturbojpeg.pc
-    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-endif()
-
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jconfig.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/jerror.h ${CMAKE_CURRENT_SOURCE_DIR}/jmorecfg.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/jpeglib.h
-  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-
-include(cmakescripts/BuildPackages.cmake)
-
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmakescripts/cmake_uninstall.cmake.in"
-  "cmake_uninstall.cmake" IMMEDIATE @ONLY)
-
-add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P cmake_uninstall.cmake)
diff --git a/src/third_party/libjpeg-turbo/ChangeLog.md b/src/third_party/libjpeg-turbo/ChangeLog.md
index 57bcf1d..ca5208b 100644
--- a/src/third_party/libjpeg-turbo/ChangeLog.md
+++ b/src/third_party/libjpeg-turbo/ChangeLog.md
@@ -1,3 +1,430 @@
+2.1.1
+=====
+
+### Significant changes relative to 2.1.0
+
+1. Fixed a regression introduced in 2.1.0 that caused build failures with
+non-GCC-compatible compilers for Un*x/Arm platforms.
+
+2. Fixed a regression introduced by 2.1 beta1[13] that prevented the Arm 32-bit
+(AArch32) Neon SIMD extensions from building unless the C compiler flags
+included `-mfloat-abi=softfp` or `-mfloat-abi=hard`.
+
+3. Fixed an issue in the AArch32 Neon SIMD Huffman encoder whereby reliance on
+undefined C compiler behavior led to crashes ("SIGBUS: illegal alignment") on
+Android systems when running AArch32/Thumb builds of libjpeg-turbo built with
+recent versions of Clang.
+
+
+2.1.0
+=====
+
+### Significant changes relative to 2.1 beta1
+
+1. Fixed a regression introduced by 2.1 beta1[6(b)] whereby attempting to
+decompress certain progressive JPEG images with one or more component planes of
+width 8 or less caused a buffer overrun.
+
+2. Fixed a regression introduced by 2.1 beta1[6(b)] whereby attempting to
+decompress a specially-crafted malformed progressive JPEG image caused the
+block smoothing algorithm to read from uninitialized memory.
+
+3. Fixed an issue in the Arm Neon SIMD Huffman encoders that caused the
+encoders to generate incorrect results when using the Clang compiler with
+Visual Studio.
+
+4. Fixed a floating point exception (CVE-2021-20205) that occurred when
+attempting to compress a specially-crafted malformed GIF image with a specified
+image width of 0 using cjpeg.
+
+5. Fixed a regression introduced by 2.0 beta1[15] whereby attempting to
+generate a progressive JPEG image on an SSE2-capable CPU using a scan script
+containing one or more scans with lengths divisible by 32 and non-zero
+successive approximation low bit positions would, under certain circumstances,
+result in an error ("Missing Huffman code table entry") and an invalid JPEG
+image.
+
+6. Introduced a new flag (`TJFLAG_LIMITSCANS` in the TurboJPEG C API and
+`TJ.FLAG_LIMIT_SCANS` in the TurboJPEG Java API) and a corresponding TJBench
+command-line argument (`-limitscans`) that causes the TurboJPEG decompression
+and transform functions/operations to return/throw an error if a progressive
+JPEG image contains an unreasonably large number of scans.  This allows
+applications that use the TurboJPEG API to guard against an exploit of the
+progressive JPEG format described in the report
+["Two Issues with the JPEG Standard"](https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf).
+
+7. The PPM reader now throws an error, rather than segfaulting (due to a buffer
+overrun) or generating incorrect pixels, if an application attempts to use the
+`tjLoadImage()` function to load a 16-bit binary PPM file (a binary PPM file
+with a maximum value greater than 255) into a grayscale image buffer or to load
+a 16-bit binary PGM file into an RGB image buffer.
+
+8. Fixed an issue in the PPM reader that caused incorrect pixels to be
+generated when using the `tjLoadImage()` function to load a 16-bit binary PPM
+file into an extended RGB image buffer.
+
+9. Fixed an issue whereby, if a JPEG buffer was automatically re-allocated by
+one of the TurboJPEG compression or transform functions and an error
+subsequently occurred during compression or transformation, the JPEG buffer
+pointer passed by the application was not updated when the function returned.
+
+
+2.0.90 (2.1 beta1)
+==================
+
+### Significant changes relative to 2.0.6:
+
+1. The build system, x86-64 SIMD extensions, and accelerated Huffman codec now
+support the x32 ABI on Linux, which allows for using x86-64 instructions with
+32-bit pointers.  The x32 ABI is generally enabled by adding `-mx32` to the
+compiler flags.
+
+     Caveats:
+     - CMake 3.9.0 or later is required in order for the build system to
+automatically detect an x32 build.
+     - Java does not support the x32 ABI, and thus the TurboJPEG Java API will
+automatically be disabled with x32 builds.
+
+2. Added Loongson MMI SIMD implementations of the RGB-to-grayscale, 4:2:2 fancy
+chroma upsampling, 4:2:2 and 4:2:0 merged chroma upsampling/color conversion,
+and fast integer DCT/IDCT algorithms.  Relative to libjpeg-turbo 2.0.x, this
+speeds up:
+
+     - the compression of RGB source images into grayscale JPEG images by
+approximately 20%
+     - the decompression of 4:2:2 JPEG images by approximately 40-60% when
+using fancy upsampling
+     - the decompression of 4:2:2 and 4:2:0 JPEG images by approximately
+15-20% when using merged upsampling
+     - the compression of RGB source images by approximately 30-45% when using
+the fast integer DCT
+     - the decompression of JPEG images into RGB destination images by
+approximately 2x when using the fast integer IDCT
+
+    The overall decompression speedup for RGB images is now approximately
+2.3-3.7x (compared to 2-3.5x with libjpeg-turbo 2.0.x.)
+
+3. 32-bit (Armv7 or Armv7s) iOS builds of libjpeg-turbo are no longer
+supported, and the libjpeg-turbo build system can no longer be used to package
+such builds.  32-bit iOS apps cannot run in iOS 11 and later, and the App Store
+no longer allows them.
+
+4. 32-bit (i386) OS X/macOS builds of libjpeg-turbo are no longer supported,
+and the libjpeg-turbo build system can no longer be used to package such
+builds.  32-bit Mac applications cannot run in macOS 10.15 "Catalina" and
+later, and the App Store no longer allows them.
+
+5. The SSE2 (x86 SIMD) and C Huffman encoding algorithms have been
+significantly optimized, resulting in a measured average overall compression
+speedup of 12-28% for 64-bit code and 22-52% for 32-bit code on various Intel
+and AMD CPUs, as well as a measured average overall compression speedup of
+0-23% on platforms that do not have a SIMD-accelerated Huffman encoding
+implementation.
+
+6. The block smoothing algorithm that is applied by default when decompressing
+progressive Huffman-encoded JPEG images has been improved in the following
+ways:
+
+     - The algorithm is now more fault-tolerant.  Previously, if a particular
+scan was incomplete, then the smoothing parameters for the incomplete scan
+would be applied to the entire output image, including the parts of the image
+that were generated by the prior (complete) scan.  Visually, this had the
+effect of removing block smoothing from lower-frequency scans if they were
+followed by an incomplete higher-frequency scan.  libjpeg-turbo now applies
+block smoothing parameters to each iMCU row based on which scan generated the
+pixels in that row, rather than always using the block smoothing parameters for
+the most recent scan.
+     - When applying block smoothing to DC scans, a Gaussian-like kernel with a
+5x5 window is used to reduce the "blocky" appearance.
+
+7. Added SIMD acceleration for progressive Huffman encoding on Arm platforms.
+This speeds up the compression of full-color progressive JPEGs by about 30-40%
+on average (relative to libjpeg-turbo 2.0.x) when using modern Arm CPUs.
+
+8. Added configure-time and run-time auto-detection of Loongson MMI SIMD
+instructions, so that the Loongson MMI SIMD extensions can be included in any
+MIPS64 libjpeg-turbo build.
+
+9. Added fault tolerance features to djpeg and jpegtran, mainly to demonstrate
+methods by which applications can guard against the exploits of the JPEG format
+described in the report
+["Two Issues with the JPEG Standard"](https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf).
+
+     - Both programs now accept a `-maxscans` argument, which can be used to
+limit the number of allowable scans in the input file.
+     - Both programs now accept a `-strict` argument, which can be used to
+treat all warnings as fatal.
+
+10. CMake package config files are now included for both the libjpeg and
+TurboJPEG API libraries.  This facilitates using libjpeg-turbo with CMake's
+`find_package()` function.  For example:
+
+        find_package(libjpeg-turbo CONFIG REQUIRED)
+
+        add_executable(libjpeg_program libjpeg_program.c)
+        target_link_libraries(libjpeg_program PUBLIC libjpeg-turbo::jpeg)
+
+        add_executable(libjpeg_program_static libjpeg_program.c)
+        target_link_libraries(libjpeg_program_static PUBLIC
+          libjpeg-turbo::jpeg-static)
+
+        add_executable(turbojpeg_program turbojpeg_program.c)
+        target_link_libraries(turbojpeg_program PUBLIC
+          libjpeg-turbo::turbojpeg)
+
+        add_executable(turbojpeg_program_static turbojpeg_program.c)
+        target_link_libraries(turbojpeg_program_static PUBLIC
+          libjpeg-turbo::turbojpeg-static)
+
+11. Since the Unisys LZW patent has long expired, cjpeg and djpeg can now
+read/write both LZW-compressed and uncompressed GIF files (feature ported from
+jpeg-6a and jpeg-9d.)
+
+12. jpegtran now includes the `-wipe` and `-drop` options from jpeg-9a and
+jpeg-9d, as well as the ability to expand the image size using the `-crop`
+option.  Refer to jpegtran.1 or usage.txt for more details.
+
+13. Added a complete intrinsics implementation of the Arm Neon SIMD extensions,
+thus providing SIMD acceleration on Arm platforms for all of the algorithms
+that are SIMD-accelerated on x86 platforms.  This new implementation is
+significantly faster in some cases than the old GAS implementation--
+depending on the algorithms used, the type of CPU core, and the compiler.  GCC,
+as of this writing, does not provide a full or optimal set of Neon intrinsics,
+so for performance reasons, the default when building libjpeg-turbo with GCC is
+to continue using the GAS implementation of the following algorithms:
+
+     - 32-bit RGB-to-YCbCr color conversion
+     - 32-bit fast and accurate inverse DCT
+     - 64-bit RGB-to-YCbCr and YCbCr-to-RGB color conversion
+     - 64-bit accurate forward and inverse DCT
+     - 64-bit Huffman encoding
+
+    A new CMake variable (`NEON_INTRINSICS`) can be used to override this
+default.
+
+    Since the new intrinsics implementation includes SIMD acceleration
+for merged upsampling/color conversion, 1.5.1[5] is no longer necessary and has
+been reverted.
+
+14. The Arm Neon SIMD extensions can now be built using Visual Studio.
+
+15. The build system can now be used to generate a universal x86-64 + Armv8
+libjpeg-turbo SDK package for both iOS and macOS.
+
+
+2.0.6
+=====
+
+### Significant changes relative to 2.0.5:
+
+1. Fixed "using JNI after critical get" errors that occurred on Android
+platforms when using any of the YUV encoding/compression/decompression/decoding
+methods in the TurboJPEG Java API.
+
+2. Fixed or worked around multiple issues with `jpeg_skip_scanlines()`:
+
+     - Fixed segfaults or "Corrupt JPEG data: premature end of data segment"
+errors in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or
+4:2:0 JPEG images using merged (non-fancy) upsampling/color conversion (that
+is, when setting `cinfo.do_fancy_upsampling` to `FALSE`.)  2.0.0[6] was a
+similar fix, but it did not cover all cases.
+     - `jpeg_skip_scanlines()` now throws an error if two-pass color
+quantization is enabled.  Two-pass color quantization never worked properly
+with `jpeg_skip_scanlines()`, and the issues could not readily be fixed.
+     - Fixed an issue whereby `jpeg_skip_scanlines()` always returned 0 when
+skipping past the end of an image.
+
+3. The Arm 64-bit (Armv8) Neon SIMD extensions can now be built using MinGW
+toolchains targetting Arm64 (AArch64) Windows binaries.
+
+4. Fixed unexpected visual artifacts that occurred when using
+`jpeg_crop_scanline()` and interblock smoothing while decompressing only the DC
+scan of a progressive JPEG image.
+
+5. Fixed an issue whereby libjpeg-turbo would not build if 12-bit-per-component
+JPEG support (`WITH_12BIT`) was enabled along with libjpeg v7 or libjpeg v8
+API/ABI emulation (`WITH_JPEG7` or `WITH_JPEG8`.)
+
+
+2.0.5
+=====
+
+### Significant changes relative to 2.0.4:
+
+1. Worked around issues in the MIPS DSPr2 SIMD extensions that caused failures
+in the libjpeg-turbo regression tests.  Specifically, the
+`jsimd_h2v1_downsample_dspr2()` and `jsimd_h2v2_downsample_dspr2()` functions
+in the MIPS DSPr2 SIMD extensions are now disabled until/unless they can be
+fixed, and other functions that are incompatible with big endian MIPS CPUs are
+disabled when building libjpeg-turbo for such CPUs.
+
+2. Fixed an oversight in the `TJCompressor.compress(int)` method in the
+TurboJPEG Java API that caused an error ("java.lang.IllegalStateException: No
+source image is associated with this instance") when attempting to use that
+method to compress a YUV image.
+
+3. Fixed an issue (CVE-2020-13790) in the PPM reader that caused a buffer
+overrun in cjpeg, TJBench, or the `tjLoadImage()` function if one of the values
+in a binary PPM/PGM input file exceeded the maximum value defined in the file's
+header and that maximum value was less than 255.  libjpeg-turbo 1.5.0 already
+included a similar fix for binary PPM/PGM files with maximum values greater
+than 255.
+
+4. The TurboJPEG API library's global error handler, which is used in functions
+such as `tjBufSize()` and `tjLoadImage()` that do not require a TurboJPEG
+instance handle, is now thread-safe on platforms that support thread-local
+storage.
+
+
+2.0.4
+=====
+
+### Significant changes relative to 2.0.3:
+
+1. Fixed a regression in the Windows packaging system (introduced by
+2.0 beta1[2]) whereby, if both the 64-bit libjpeg-turbo SDK for GCC and the
+64-bit libjpeg-turbo SDK for Visual C++ were installed on the same system, only
+one of them could be uninstalled.
+
+2. Fixed a signed integer overflow and subsequent segfault that occurred when
+attempting to decompress images with more than 715827882 pixels using the
+64-bit C version of TJBench.
+
+3. Fixed out-of-bounds write in `tjDecompressToYUV2()` and
+`tjDecompressToYUVPlanes()` (sometimes manifesting as a double free) that
+occurred when attempting to decompress grayscale JPEG images that were
+compressed with a sampling factor other than 1 (for instance, with
+`cjpeg -grayscale -sample 2x2`).
+
+4. Fixed a regression introduced by 2.0.2[5] that caused the TurboJPEG API to
+incorrectly identify some JPEG images with unusual sampling factors as 4:4:4
+JPEG images.  This was known to cause a buffer overflow when attempting to
+decompress some such images using `tjDecompressToYUV2()` or
+`tjDecompressToYUVPlanes()`.
+
+5. Fixed an issue (CVE-2020-17541), detected by ASan, whereby attempting to
+losslessly transform a specially-crafted malformed JPEG image containing an
+extremely-high-frequency coefficient block (junk image data that could never be
+generated by a legitimate JPEG compressor) could cause the Huffman encoder's
+local buffer to be overrun. (Refer to 1.4.0[9] and 1.4beta1[15].)  Given that
+the buffer overrun was fully contained within the stack and did not cause a
+segfault or other user-visible errant behavior, and given that the lossless
+transformer (unlike the decompressor) is not generally exposed to arbitrary
+data exploits, this issue did not likely pose a security risk.
+
+6. The Arm 64-bit (Armv8) Neon SIMD assembly code now stores constants in a
+separate read-only data section rather than in the text section, to support
+execute-only memory layouts.
+
+
+2.0.3
+=====
+
+### Significant changes relative to 2.0.2:
+
+1. Fixed "using JNI after critical get" errors that occurred on Android
+platforms when passing invalid arguments to certain methods in the TurboJPEG
+Java API.
+
+2. Fixed a regression in the SIMD feature detection code, introduced by
+the AVX2 SIMD extensions (2.0 beta1[1]), that was known to cause an illegal
+instruction exception, in rare cases, on CPUs that lack support for CPUID leaf
+07H (or on which the maximum CPUID leaf has been limited by way of a BIOS
+setting.)
+
+3. The 4:4:0 (h1v2) fancy (smooth) chroma upsampling algorithm in the
+decompressor now uses a similar bias pattern to that of the 4:2:2 (h2v1) fancy
+chroma upsampling algorithm, rounding up or down the upsampled result for
+alternate pixels rather than always rounding down.  This ensures that,
+regardless of whether a 4:2:2 JPEG image is rotated or transposed prior to
+decompression (in the frequency domain) or after decompression (in the spatial
+domain), the final image will be similar.
+
+4. Fixed an integer overflow and subsequent segfault that occurred when
+attempting to compress or decompress images with more than 1 billion pixels
+using the TurboJPEG API.
+
+5. Fixed a regression introduced by 2.0 beta1[15] whereby attempting to
+generate a progressive JPEG image on an SSE2-capable CPU using a scan script
+containing one or more scans with lengths divisible by 16 would result in an
+error ("Missing Huffman code table entry") and an invalid JPEG image.
+
+6. Fixed an issue whereby `tjDecodeYUV()` and `tjDecodeYUVPlanes()` would throw
+an error ("Invalid progressive parameters") or a warning ("Inconsistent
+progression sequence") if passed a TurboJPEG instance that was previously used
+to decompress a progressive JPEG image.
+
+
+2.0.2
+=====
+
+### Significant changes relative to 2.0.1:
+
+1. Fixed a regression introduced by 2.0.1[5] that prevented a runtime search
+path (rpath) from being embedded in the libjpeg-turbo shared libraries and
+executables for macOS and iOS.  This caused a fatal error of the form
+"dyld: Library not loaded" when attempting to use one of the executables,
+unless `DYLD_LIBRARY_PATH` was explicitly set to the location of the
+libjpeg-turbo shared libraries.
+
+2. Fixed an integer overflow and subsequent segfault (CVE-2018-20330) that
+occurred when attempting to load a BMP file with more than 1 billion pixels
+using the `tjLoadImage()` function.
+
+3. Fixed a buffer overrun (CVE-2018-19664) that occurred when attempting to
+decompress a specially-crafted malformed JPEG image to a 256-color BMP using
+djpeg.
+
+4. Fixed a floating point exception that occurred when attempting to
+decompress a specially-crafted malformed JPEG image with a specified image
+width or height of 0 using the C version of TJBench.
+
+5. The TurboJPEG API will now decompress 4:4:4 JPEG images with 2x1, 1x2, 3x1,
+or 1x3 luminance and chrominance sampling factors.  This is a non-standard way
+of specifying 1x subsampling (normally 4:4:4 JPEGs have 1x1 luminance and
+chrominance sampling factors), but the JPEG format and the libjpeg API both
+allow it.
+
+6. Fixed a regression introduced by 2.0 beta1[7] that caused djpeg to generate
+incorrect PPM images when used with the `-colors` option.
+
+7. Fixed an issue whereby a static build of libjpeg-turbo (a build in which
+`ENABLE_SHARED` is `0`) could not be installed using the Visual Studio IDE.
+
+8. Fixed a severe performance issue in the Loongson MMI SIMD extensions that
+occurred when compressing RGB images whose image rows were not 64-bit-aligned.
+
+
+2.0.1
+=====
+
+### Significant changes relative to 2.0.0:
+
+1. Fixed a regression introduced with the new CMake-based Un*x build system,
+whereby jconfig.h could cause compiler warnings of the form
+`"HAVE_*_H" redefined` if it was included by downstream Autotools-based
+projects that used `AC_CHECK_HEADERS()` to check for the existence of locale.h,
+stddef.h, or stdlib.h.
+
+2. The `jsimd_quantize_float_dspr2()` and `jsimd_convsamp_float_dspr2()`
+functions in the MIPS DSPr2 SIMD extensions are now disabled at compile time
+if the soft float ABI is enabled.  Those functions use instructions that are
+incompatible with the soft float ABI.
+
+3. Fixed a regression in the SIMD feature detection code, introduced by
+the AVX2 SIMD extensions (2.0 beta1[1]), that caused libjpeg-turbo to crash on
+Windows 7 if Service Pack 1 was not installed.
+
+4. Fixed out-of-bounds read in cjpeg that occurred when attempting to compress
+a specially-crafted malformed color-index (8-bit-per-sample) Targa file in
+which some of the samples (color indices) exceeded the bounds of the Targa
+file's color table.
+
+5. Fixed an issue whereby installing a fully static build of libjpeg-turbo
+(a build in which `CFLAGS` contains `-static` and `ENABLE_SHARED` is `0`) would
+fail with "No valid ELF RPATH or RUNPATH entry exists in the file."
+
+
 2.0.0
 =====
 
@@ -11,6 +438,54 @@
 `tjDecompressToYUVPlanes()`, `tjDecompressToYUV2()`, or the equivalent Java
 methods.
 
+2. Fixed an issue (CVE-2018-11813) whereby a specially-crafted malformed input
+file (specifically, a file with a valid Targa header but incomplete pixel data)
+would cause cjpeg to generate a JPEG file that was potentially thousands of
+times larger than the input file.  The Targa reader in cjpeg was not properly
+detecting that the end of the input file had been reached prematurely, so after
+all valid pixels had been read from the input, the reader injected dummy pixels
+with values of 255 into the JPEG compressor until the number of pixels
+specified in the Targa header had been compressed.  The Targa reader in cjpeg
+now behaves like the PPM reader and aborts compression if the end of the input
+file is reached prematurely.  Because this issue only affected cjpeg and not
+the underlying library, and because it did not involve any out-of-bounds reads
+or other exploitable behaviors, it was not believed to represent a security
+threat.
+
+3. Fixed an issue whereby the `tjLoadImage()` and `tjSaveImage()` functions
+would produce a "Bogus message code" error message if the underlying bitmap and
+PPM readers/writers threw an error that was specific to the readers/writers
+(as opposed to a general libjpeg API error.)
+
+4. Fixed an issue (CVE-2018-1152) whereby a specially-crafted malformed BMP
+file, one in which the header specified an image width of 1073741824 pixels,
+would trigger a floating point exception (division by zero) in the
+`tjLoadImage()` function when attempting to load the BMP file into a
+4-component image buffer.
+
+5. Fixed an issue whereby certain combinations of calls to
+`jpeg_skip_scanlines()` and `jpeg_read_scanlines()` could trigger an infinite
+loop when decompressing progressive JPEG images that use vertical chroma
+subsampling (for instance, 4:2:0 or 4:4:0.)
+
+6. Fixed a segfault in `jpeg_skip_scanlines()` that occurred when decompressing
+a 4:2:2 or 4:2:0 JPEG image using the merged (non-fancy) upsampling algorithms
+(that is, when setting `cinfo.do_fancy_upsampling` to `FALSE`.)
+
+7. The new CMake-based build system will now disable the MIPS DSPr2 SIMD
+extensions if it detects that the compiler does not support DSPr2 instructions.
+
+8. Fixed out-of-bounds read in cjpeg (CVE-2018-14498) that occurred when
+attempting to compress a specially-crafted malformed color-index
+(8-bit-per-sample) BMP file in which some of the samples (color indices)
+exceeded the bounds of the BMP file's color table.
+
+9. Fixed a signed integer overflow in the progressive Huffman decoder, detected
+by the Clang and GCC undefined behavior sanitizers, that could be triggered by
+attempting to decompress a specially-crafted malformed JPEG image.  This issue
+did not pose a security threat, but removing the warning made it easier to
+detect actual security issues, should they arise in the future.
+
 
 1.5.90 (2.0 beta1)
 ==================
@@ -19,7 +494,7 @@
 
 1. Added AVX2 SIMD implementations of the colorspace conversion, chroma
 downsampling and upsampling, integer quantization and sample conversion, and
-slow integer DCT/IDCT algorithms.  When using the slow integer DCT/IDCT
+accurate integer DCT/IDCT algorithms.  When using the accurate integer DCT/IDCT
 algorithms on AVX2-equipped CPUs, the compression of RGB images is
 approximately 13-36% (avg. 22%) faster (relative to libjpeg-turbo 1.5.x) with
 64-bit code and 11-21% (avg. 17%) faster with 32-bit code, and the
@@ -123,16 +598,16 @@
 now produces bitwise-identical results to the unmerged algorithms.
 
 12. The SIMD function symbols for x86[-64]/ELF, MIPS/ELF, macOS/x86[-64] (if
-libjpeg-turbo is built with YASM), and iOS/ARM[64] builds are now private.
+libjpeg-turbo is built with YASM), and iOS/Arm[64] builds are now private.
 This prevents those symbols from being exposed in applications or shared
 libraries that link statically with libjpeg-turbo.
 
 13. Added Loongson MMI SIMD implementations of the RGB-to-YCbCr and
 YCbCr-to-RGB colorspace conversion, 4:2:0 chroma downsampling, 4:2:0 fancy
-chroma upsampling, integer quantization, and slow integer DCT/IDCT algorithms.
-When using the slow integer DCT/IDCT, this speeds up the compression of RGB
-images by approximately 70-100% and the decompression of RGB images by
-approximately 2-3.5x.
+chroma upsampling, integer quantization, and accurate integer DCT/IDCT
+algorithms.  When using the accurate integer DCT/IDCT, this speeds up the
+compression of RGB images by approximately 70-100% and the decompression of RGB
+images by approximately 2-3.5x.
 
 14. Fixed a build error when building with older MinGW releases (regression
 caused by 1.5.1[7].)
@@ -163,8 +638,8 @@
 output format other than PPM/PGM, GIF, or Targa is selected along with the
 `-crop` option.
 
-4. Fixed an issue whereby `jpeg_skip_scanlines()` would segfault if color
-quantization was enabled.
+4. Fixed an issue (CVE-2017-15232) whereby `jpeg_skip_scanlines()` would
+segfault if color quantization was enabled.
 
 5. TJBench (both C and Java versions) will now display usage information if any
 command-line argument is unrecognized.  This prevents the program from silently
@@ -182,9 +657,9 @@
 `jpeg_consume_input()` would return `JPEG_SUSPENDED` rather than
 `JPEG_REACHED_EOI`.
 
-9. `jpeg_crop_scanlines()` now works correctly when decompressing grayscale
-JPEG images that were compressed with a sampling factor other than 1 (for
-instance, with `cjpeg -grayscale -sample 2x2`).
+9. `jpeg_crop_scanline()` now works correctly when decompressing grayscale JPEG
+images that were compressed with a sampling factor other than 1 (for instance,
+with `cjpeg -grayscale -sample 2x2`).
 
 
 1.5.2
@@ -208,7 +683,7 @@
 5. Fixed build and runtime errors on Windows that occurred when building
 libjpeg-turbo with libjpeg v7 API/ABI emulation and the in-memory
 source/destination managers.  Due to an oversight, the `jpeg_skip_scanlines()`
-and `jpeg_crop_scanlines()` functions were not being included in jpeg7.dll when
+and `jpeg_crop_scanline()` functions were not being included in jpeg7.dll when
 libjpeg-turbo was built with `-DWITH_JPEG7=1` and `-DWITH_MEMSRCDST=1`.
 
 6. Fixed "Bogus virtual array access" error that occurred when using the
@@ -319,8 +794,8 @@
 2x2 luminance sampling factors and 2x1 or 1x2 chrominance sampling factors.
 This is a non-standard way of specifying 2x subsampling (normally 4:2:2 JPEGs
 have 2x1 luminance and 1x1 chrominance sampling factors, and 4:4:0 JPEGs have
-1x2 luminance and 1x1 chrominance sampling factors), but the JPEG specification
-and the libjpeg API both allow it.
+1x2 luminance and 1x1 chrominance sampling factors), but the JPEG format and
+the libjpeg API both allow it.
 
 7. Fixed an unsigned integer overflow in the libjpeg memory manager, detected
 by the Clang undefined behavior sanitizer, that could be triggered by
@@ -365,10 +840,10 @@
 
 3. Fixed a couple of issues in the PPM reader that would cause buffer overruns
 in cjpeg if one of the values in a binary PPM/PGM input file exceeded the
-maximum value defined in the file's header.  libjpeg-turbo 1.4.2 already
-included a similar fix for ASCII PPM/PGM files.  Note that these issues were
-not security bugs, since they were confined to the cjpeg program and did not
-affect any of the libjpeg-turbo libraries.
+maximum value defined in the file's header and that maximum value was greater
+than 255.  libjpeg-turbo 1.4.2 already included a similar fix for ASCII PPM/PGM
+files.  Note that these issues were not security bugs, since they were confined
+to the cjpeg program and did not affect any of the libjpeg-turbo libraries.
 
 4. Fixed an issue whereby attempting to decompress a JPEG file with a corrupt
 header using the `tjDecompressToYUV2()` function would cause the function to
@@ -464,8 +939,8 @@
 disabled by setting the `JSIMD_NOHUFFENC` environment variable to `1`.
 
 13. Added ARM 64-bit (ARMv8) NEON SIMD implementations of the commonly-used
-compression algorithms (including the slow integer forward DCT and h2v2 & h2v1
-downsampling algorithms, which are not accelerated in the 32-bit NEON
+compression algorithms (including the accurate integer forward DCT and h2v2 &
+h2v1 downsampling algorithms, which are not accelerated in the 32-bit NEON
 implementation.)  This speeds up the compression of full-color JPEGs by about
 75% on average on a Cavium ThunderX processor and by about 2-2.5x on average on
 Cortex-A53 and Cortex-A57 cores.
@@ -596,8 +1071,8 @@
 
 7. Fixed an extremely rare bug in the Huffman encoder that caused 64-bit
 builds of libjpeg-turbo to incorrectly encode a few specific test images when
-quality=98, an optimized Huffman table, and the slow integer forward DCT were
-used.
+quality=98, an optimized Huffman table, and the accurate integer forward DCT
+were used.
 
 8. The Windows (CMake) build system now supports building only static or only
 shared libraries.  This is accomplished by adding either `-DENABLE_STATIC=0` or
@@ -756,8 +1231,8 @@
 The accuracy of this implementation now matches the accuracy of the SSE/SSE2
 implementation.  Note, however, that the floating point DCT/IDCT algorithms are
 mainly a legacy feature.  They generally do not produce significantly better
-accuracy than the slow integer DCT/IDCT algorithms, and they are quite a bit
-slower.
+accuracy than the accurate integer DCT/IDCT algorithms, and they are quite a
+bit slower.
 
 8. Added a new output colorspace (`JCS_RGB565`) to the libjpeg API that allows
 for decompressing JPEG images into RGB565 (16-bit) pixels.  If dithering is not
@@ -791,13 +1266,13 @@
 reasons (probably related to clang), this code cannot currently be compiled for
 iOS.
 
-15. Fixed an extremely rare bug that could cause the Huffman encoder's local
-buffer to overrun when a very high-frequency MCU is compressed using quality
-100 and no subsampling, and when the JPEG output buffer is being dynamically
-resized by the destination manager.  This issue was so rare that, even with a
-test program specifically designed to make the bug occur (by injecting random
-high-frequency YUV data into the compressor), it was reproducible only once in
-about every 25 million iterations.
+15. Fixed an extremely rare bug (CVE-2014-9092) that could cause the Huffman
+encoder's local buffer to overrun when a very high-frequency MCU is compressed
+using quality 100 and no subsampling, and when the JPEG output buffer is being
+dynamically resized by the destination manager.  This issue was so rare that,
+even with a test program specifically designed to make the bug occur (by
+injecting random high-frequency YUV data into the compressor), it was
+reproducible only once in about every 25 million iterations.
 
 16. Fixed an oversight in the TurboJPEG C wrapper:  if any of the JPEG
 compression functions was called repeatedly with the same
@@ -832,8 +1307,9 @@
 jpegtran, for instance) would result in an error, `Requested feature was
 omitted at compile time`.
 
-4. Fixed a couple of issues whereby malformed JPEG images would cause
-libjpeg-turbo to use uninitialized memory during decompression.
+4. Fixed a couple of issues (CVE-2013-6629 and CVE-2013-6630) whereby malformed
+JPEG images would cause libjpeg-turbo to use uninitialized memory during
+decompression.
 
 5. Fixed an error (`Buffer passed to JPEG library is too small`) that occurred
 when calling the TurboJPEG YUV encoding function with a very small (< 5x5)
@@ -972,9 +1448,9 @@
 upper 64 bits of xmm6 and xmm7 on Win64 platforms, which violated the Win64
 calling conventions.
 
-4. Fixed a regression caused by 1.2.0[6] whereby decompressing corrupt JPEG
-images (specifically, images in which the component count was erroneously set
-to a large value) would cause libjpeg-turbo to segfault.
+4. Fixed a regression (CVE-2012-2806) caused by 1.2.0[6] whereby decompressing
+corrupt JPEG images (specifically, images in which the component count was
+erroneously set to a large value) would cause libjpeg-turbo to segfault.
 
 5. Worked around a severe performance issue with "Bobcat" (AMD Embedded APU)
 processors.  The `MASKMOVDQU` instruction, which was used by the libjpeg-turbo
@@ -1166,8 +1642,8 @@
 
 2. Despite the above, the fast integer forward DCT still degrades somewhat for
 JPEG qualities greater than 95, so the TurboJPEG wrapper will now automatically
-use the slow integer forward DCT when generating JPEG images of quality 96 or
-greater.  This reduces compression performance by as much as 15% for these
+use the accurate integer forward DCT when generating JPEG images of quality 96
+or greater.  This reduces compression performance by as much as 15% for these
 high-quality images but is necessary to ensure that the images are perceptually
 lossless.  It also ensures that the library can avoid the performance pitfall
 created by [1].
diff --git a/src/third_party/libjpeg-turbo/DIR_METADATA b/src/third_party/libjpeg-turbo/DIR_METADATA
new file mode 100644
index 0000000..8bc04f1
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/DIR_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "Internals>Images>Codecs"
+}
diff --git a/src/third_party/libjpeg-turbo/LICENSE.md b/src/third_party/libjpeg-turbo/LICENSE.md
index 0f6ec4b..a1cdad5 100644
--- a/src/third_party/libjpeg-turbo/LICENSE.md
+++ b/src/third_party/libjpeg-turbo/LICENSE.md
@@ -14,7 +14,7 @@
   This license covers the TurboJPEG API library and associated programs, as
   well as the build system.
 
-- The zlib License, which is listed below
+- The [zlib License](https://opensource.org/licenses/Zlib)
 
   This license is a subset of the other two, and it covers the libjpeg-turbo
   SIMD extensions.
@@ -66,7 +66,7 @@
 
     2.  If your binary distribution includes or uses the TurboJPEG API, then
         your product documentation must include the text of the Modified BSD
-        License.
+        License (see below.)
 
         **Origin**
         - Clause 2 of the Modified BSD License
@@ -91,7 +91,8 @@
 The Modified (3-clause) BSD License
 ===================================
 
-Copyright (C)\<YEAR\> \<AUTHOR\>.  All Rights Reserved.
+Copyright (C)2009-2021 D. R. Commander.  All Rights Reserved.<br>
+Copyright (C)2015 Viktor Szathmáry.  All Rights Reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -118,28 +119,6 @@
 POSSIBILITY OF SUCH DAMAGE.
 
 
-The zlib License
-================
-
-Copyright (C) \<YEAR\>, \<AUTHOR\>.
-
-This software is provided 'as-is', without any express or implied
-warranty.  In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
-   claim that you wrote the original software. If you use this software
-   in a product, an acknowledgment in the product documentation would be
-   appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
-   misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-
-
 Why Three Licenses?
 ===================
 
diff --git a/src/third_party/libjpeg-turbo/METADATA b/src/third_party/libjpeg-turbo/METADATA
index 35e49ff..81d7ca0 100644
--- a/src/third_party/libjpeg-turbo/METADATA
+++ b/src/third_party/libjpeg-turbo/METADATA
@@ -5,17 +5,14 @@
 third_party {
   url {
     type: GIT
-    value: "https://github.com/libjpeg-turbo/libjpeg-turbo"
+    value: "https://chromium.googlesource.com/chromium/deps/libjpeg_turbo/"
   }
-  # Note: We initially added a version of libjpeg-turbo that was in between
-  # versions 2.0.0 and 1.5.91. The version and last upgrade date below should
-  # reflect the point in between those two versions when the library was first
-  # brought into Cobalt.
-  version: "1a85fc497db85e1bf8b026d51cf6e5dec391d224"
+  # Version 2.1.0
+  version: "b201838d8b5f2f80c9f86ec8405a62a002232b2c"
   last_upgrade_date {
-    year: 2018
-    month: 5
-    day: 21
+    year: 2021
+    month: 7
+    day: 13
   }
   license_type: NOTICE
 }
diff --git a/src/third_party/libjpeg-turbo/README.chromium b/src/third_party/libjpeg-turbo/README.chromium
new file mode 100644
index 0000000..de1fe85
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/README.chromium
@@ -0,0 +1,70 @@
+Name: libjpeg-turbo
+URL: https://github.com/libjpeg-turbo/libjpeg-turbo/
+Version: b201838d8b5f2f80c9f86ec8405a62a002232b2c (post 2.1.0)
+License: Custom license
+License File: LICENSE.md
+Security Critical: yes
+License Android Compatible: yes
+
+Description:
+This consists of the components:
+* libjpeg-turbo b201838d8b5f2f80c9f86ec8405a62a002232b2c (post 2.1.0)
+* This file (README.chromium)
+* A build file (BUILD.gn)
+* An OWNERS file
+* A codereview.settings file
+* Patched header files used by Chromium
+* Deleted unused directories: cmakescripts, doc, fuzz, java, release,
+  sharedlib, simd/loongson, simd/mips, simd/powerpc, and win
+* Deleted unused files: appveyor.yml, CMakeLists.txt, doxygen.config,
+  doxygen-extra.css, .gitattributes, md5/CMakeLists.txt, md5/md5cmp.c,
+  simd/CMakeLists.txt, tjexample.c, tjexampletest.in, tjexampletest.java.in and
+  .travis.yml
+* Deleted legacy Arm Neon assembly files (supporting old compiler versions that
+  do not generate performant code from intrinsics):
+  simd/arm/aarch32/jsimd_neon.S, simd/arm/aarch64/jsimd_neon.S.
+
+This libjpeg-turbo can replace our libjpeg-6b without any modifications in the
+Chromium code.
+
+Same as our copy of libjpeg-6b, this libjpeg-turbo also added a new file
+jpeglibmangler.h and included it from jpeglib.h that changes the names of all
+externally visible functions to chromium_* so that we can avoid conflicts that
+arise when system libraries attempt to use our libjpeg. Also, we applied the
+following changes which are not merged to upstream:
+
+* Configuration files jconfig.h, jconfigint.h and neon-compat.h were generated
+  and then altered manually to be compatible on all of Chromium's platforms.
+  http://crbug.com/608347
+* Fix static const data duplication of jpeg_nbits_table. A unique copy
+  was in the jchuff.obj and jcphuff.obj resulting in an added 65k in
+  .rdata in chrome.dll and chrome_child.dll.  Declaring extern const
+  in the header instead of static const and moving the definition to
+  a new .c file fixes this so only one copy is referenced. Also added
+  extern wrappers around usage in asm files. The jpeg_nbits_table.inc
+  file was also deleted. It was also necessary to give this table hidden
+  visibility to avoid invalid relocations (ignored by ld but rejected by
+  lld) arising from attempts to reference the table from assembler on
+  32-bit x86. This only affects shared libraries, but that's important
+  for downstream Android builds.
+* Patches to enable running the upstream unit tests through GTest.
+  The upstream unit tests are defined here under the section 'TESTS':
+  https://github.com/libjpeg-turbo/libjpeg-turbo/blob/master/CMakeLists.txt
+  These changes are tracked by Chromium issue: https://crbug.com/993876
+  - Refactor tjunittest.c to provide test interface
+  - Move tjunittest logs from stdout to stderr
+  - Refactor tjbench.c to provide test interface
+  - Move tbench logs from stdout to stderr
+  - Write tjunittest output files to sdcard on Android
+  - Refactor cjpeg.c to provide test interface
+  - Refactor jpegtran.c to provide test interface
+  - Add input JPEG images for djpeg and jpegtran tests
+  - Refactor djpeg.c to provide test interface
+  A new gtest directory contains GTest wrappers (and associated utilities) for
+  each of tjunittest, tjbench, cjpeg, djpeg and jpegtran.
+
+Refer to working-with-nested-repos [1] for details of how to setup your git
+svn client to update the code (for making local changes, cherry picking from
+upstream, etc).
+
+[1] https://www.chromium.org/developers/how-tos/get-the-code/working-with-nested-repos
diff --git a/src/third_party/libjpeg-turbo/README.ijg b/src/third_party/libjpeg-turbo/README.ijg
index c4eb7db..9453c19 100644
--- a/src/third_party/libjpeg-turbo/README.ijg
+++ b/src/third_party/libjpeg-turbo/README.ijg
@@ -128,7 +128,7 @@
 fitness for a particular purpose.  This software is provided "AS IS", and you,
 its user, assume the entire risk as to its quality and accuracy.
 
-This software is copyright (C) 1991-2016, Thomas G. Lane, Guido Vollbeding.
+This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
 All Rights Reserved except as specified below.
 
 Permission is hereby granted to use, copy, modify, and distribute this
@@ -159,19 +159,6 @@
 assumed by the product vendor.
 
 
-The IJG distribution formerly included code to read and write GIF files.
-To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
-support has been removed altogether, and the GIF writer has been simplified
-to produce "uncompressed GIFs".  This technique does not use the LZW
-algorithm; the resulting GIF files are larger than usual, but are readable
-by all standard GIF decoders.
-
-We are required to state that
-    "The Graphics Interchange Format(c) is the Copyright property of
-    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
-    CompuServe Incorporated."
-
-
 REFERENCES
 ==========
 
@@ -223,12 +210,12 @@
 A PDF file of the older JFIF 1.02 specification is available at
 http://www.w3.org/Graphics/JPEG/jfif3.pdf.
 
-The TIFF 6.0 file format specification can be obtained by FTP from
-ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation scheme
-found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
-IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
-Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
-(Compression tag 7).  Copies of this Note can be obtained from
+The TIFF 6.0 file format specification can be obtained from
+http://mirrors.ctan.org/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation
+scheme found in the TIFF 6.0 spec of 3-June-92 has a number of serious
+problems.  IJG does not recommend use of the TIFF 6.0 design (TIFF Compression
+tag 6).  Instead, we recommend the JPEG design proposed by TIFF Technical Note
+#2 (Compression tag 7).  Copies of this Note can be obtained from
 http://www.ijg.org/files/.  It is expected that the next revision
 of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
 Although IJG's own code does not support TIFF/JPEG, the free libtiff library
@@ -243,14 +230,8 @@
 directory "files".
 
 The JPEG FAQ (Frequently Asked Questions) article is a source of some
-general information about JPEG.
-It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
-and other news.answers archive sites, including the official news.answers
-archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
-If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
-with body
-        send usenet/news.answers/jpeg-faq/part1
-        send usenet/news.answers/jpeg-faq/part2
+general information about JPEG.  It is available at
+http://www.faqs.org/faqs/jpeg-faq.
 
 
 FILE FORMAT COMPATIBILITY
@@ -263,7 +244,7 @@
 are incompatible with the DCT-based JPEG standard or with JFIF (for instance,
 JPEG 2000 and JPEG XR).  This software therefore does not support these
 formats.  Indeed, one of the original reasons for developing this free software
-was to help force convergence on common, interoperable format standards for
+was to help force convergence on a common, interoperable format standard for
 JPEG files.
 
 JFIF is a minimal or "low end" representation.  TIFF/JPEG (TIFF revision 6.0 as
diff --git a/src/third_party/libjpeg-turbo/README.md b/src/third_party/libjpeg-turbo/README.md
index a769259..01e391e 100644
--- a/src/third_party/libjpeg-turbo/README.md
+++ b/src/third_party/libjpeg-turbo/README.md
@@ -1,14 +1,14 @@
 Background
 ==========
 
-libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
-AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
-on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
-compression on x86 and x86-64 systems.  On such systems, libjpeg-turbo is
-generally 2-6x as fast as libjpeg, all else being equal.  On other types of
-systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
-virtue of its highly-optimized Huffman coding routines.  In many cases, the
-performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
+libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate
+baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and
+MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm
+systems.  On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg,
+all else being equal.  On other types of systems, libjpeg-turbo can still
+outperform libjpeg by a significant amount, by virtue of its highly-optimized
+Huffman coding routines.  In many cases, the performance of libjpeg-turbo
+rivals that of proprietary high-speed JPEG codecs.
 
 libjpeg-turbo implements both the traditional libjpeg API as well as the less
 powerful but more straightforward TurboJPEG API.  libjpeg-turbo also features
@@ -135,25 +135,24 @@
 libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all
 cases (see below.)
 
-By passing an argument of `--with-jpeg7` or `--with-jpeg8` to `configure`, or
-an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you can build a
-version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that
-programs that are built against libjpeg v7 or v8 can be run with libjpeg-turbo.
-The following section describes which libjpeg v7+ features are supported and
-which aren't.
+By passing an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you
+can build a version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so
+that programs that are built against libjpeg v7 or v8 can be run with
+libjpeg-turbo.  The following section describes which libjpeg v7+ features are
+supported and which aren't.
 
 ### Support for libjpeg v7 and v8 Features
 
 #### Fully supported
 
-- **libjpeg: IDCT scaling extensions in decompressor**<br>
+- **libjpeg API: IDCT scaling extensions in decompressor**<br>
   libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8,
   1/2, 5/8, 3/4, 7/8, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 15/8, and 2/1 (only 1/4
   and 1/2 are SIMD-accelerated.)
 
-- **libjpeg: Arithmetic coding**
+- **libjpeg API: Arithmetic coding**
 
-- **libjpeg: In-memory source and destination managers**<br>
+- **libjpeg API: In-memory source and destination managers**<br>
   See notes below.
 
 - **cjpeg: Separate quality settings for luminance and chrominance**<br>
@@ -180,19 +179,19 @@
 
 NOTE:  As of this writing, extensive research has been conducted into the
 usefulness of DCT scaling as a means of data reduction and SmartScale as a
-means of quality improvement.  The reader is invited to peruse the research at
-<http://www.libjpeg-turbo.org/About/SmartScale> and draw his/her own conclusions,
+means of quality improvement.  Readers are invited to peruse the research at
+<http://www.libjpeg-turbo.org/About/SmartScale> and draw their own conclusions,
 but it is the general belief of our project that these features have not
 demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
 
-- **libjpeg: DCT scaling in compressor**<br>
+- **libjpeg API: DCT scaling in compressor**<br>
   `cinfo.scale_num` and `cinfo.scale_denom` are silently ignored.
   There is no technical reason why DCT scaling could not be supported when
   emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see
   below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and
   8/9 would be available, which is of limited usefulness.
 
-- **libjpeg: SmartScale**<br>
+- **libjpeg API: SmartScale**<br>
   `cinfo.block_size` is silently ignored.
   SmartScale is an extension to the JPEG format that allows for DCT block
   sizes other than 8x8.  Providing support for this new format would be
@@ -205,7 +204,7 @@
   interest in providing this feature would be as a means of supporting
   additional DCT scaling factors.
 
-- **libjpeg: Fancy downsampling in compressor**<br>
+- **libjpeg API: Fancy downsampling in compressor**<br>
   `cinfo.do_fancy_downsampling` is silently ignored.
   This requires the DCT scaling feature, which is not supported.
 
@@ -247,15 +246,14 @@
 libjpeg-turbo binaries.
 
 Those who are concerned about maintaining strict conformance with the libjpeg
-v6b or v7 API can pass an argument of `--without-mem-srcdst` to `configure` or
-an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to building
-libjpeg-turbo.  This will restore the pre-1.3 behavior, in which
+v6b or v7 API can pass an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to
+building libjpeg-turbo.  This will restore the pre-1.3 behavior, in which
 `jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
 libjpeg v8 API/ABI.
 
 On Un*x systems, including the in-memory source/destination managers changes
-the dynamic library version from 62.1.0 to 62.2.0 if using libjpeg v6b API/ABI
-emulation and from 7.1.0 to 7.2.0 if using libjpeg v7 API/ABI emulation.
+the dynamic library version from 62.2.0 to 62.3.0 if using libjpeg v6b API/ABI
+emulation and from 7.2.0 to 7.3.0 if using libjpeg v7 API/ABI emulation.
 
 Note that, on most Un*x systems, the dynamic linker will not look for a
 function in a library until that function is actually used.  Thus, if a program
@@ -289,12 +287,13 @@
   (and slightly faster) floating point IDCT algorithm introduced in libjpeg
   v8a as opposed to the algorithm used in libjpeg v6b.  It should be noted,
   however, that this algorithm basically brings the accuracy of the floating
-  point IDCT in line with the accuracy of the slow integer IDCT.  The floating
-  point DCT/IDCT algorithms are mainly a legacy feature, and they do not
-  produce significantly more accuracy than the slow integer algorithms (to put
-  numbers on this, the typical difference in PNSR between the two algorithms
-  is less than 0.10 dB, whereas changing the quality level by 1 in the upper
-  range of the quality scale is typically more like a 1.0 dB difference.)
+  point IDCT in line with the accuracy of the accurate integer IDCT.  The
+  floating point DCT/IDCT algorithms are mainly a legacy feature, and they do
+  not produce significantly more accuracy than the accurate integer algorithms
+  (to put numbers on this, the typical difference in PNSR between the two
+  algorithms is less than 0.10 dB, whereas changing the quality level by 1 in
+  the upper range of the quality scale is typically more like a 1.0 dB
+  difference.)
 
 - If the floating point algorithms in libjpeg-turbo are not implemented using
   SIMD instructions on a particular platform, then the accuracy of the
@@ -331,7 +330,7 @@
 necessary to use the slow Huffman decoder when decompressing a JPEG image that
 has restart markers.  This can cause the decompression performance to drop by
 as much as 20%, but the performance will still be much greater than that of
-libjpeg.  Many consumer packages, such as PhotoShop, use restart markers when
+libjpeg.  Many consumer packages, such as Photoshop, use restart markers when
 generating JPEG images, so images generated by those programs will experience
 this issue.
 
@@ -342,5 +341,17 @@
 correct results whenever the fast integer forward DCT is used along with a JPEG
 quality of 98-100.  Thus, libjpeg-turbo must use the non-SIMD quantization
 function in those cases.  This causes performance to drop by as much as 40%.
-It is therefore strongly advised that you use the slow integer forward DCT
+It is therefore strongly advised that you use the accurate integer forward DCT
 whenever encoding images with a JPEG quality of 98 or higher.
+
+
+Memory Debugger Pitfalls
+========================
+
+Valgrind and Memory Sanitizer (MSan) can generate false positives
+(specifically, incorrect reports of uninitialized memory accesses) when used
+with libjpeg-turbo's SIMD extensions.  It is generally recommended that the
+SIMD extensions be disabled, either by passing an argument of `-DWITH_SIMD=0`
+to `cmake` when configuring the build or by setting the environment variable
+`JSIMD_FORCENONE` to `1` at run time, when testing libjpeg-turbo with Valgrind,
+MSan, or other memory debuggers.
diff --git a/src/third_party/libjpeg-turbo/cderror.h b/src/third_party/libjpeg-turbo/cderror.h
index 37034a9..2844346 100644
--- a/src/third_party/libjpeg-turbo/cderror.h
+++ b/src/third_party/libjpeg-turbo/cderror.h
@@ -1,9 +1,11 @@
 /*
  * cderror.h
  *
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1997, Thomas G. Lane.
- * Modified 2009 by Guido Vollbeding.
- * This file is part of the Independent JPEG Group's software.
+ * Modified 2009-2017 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -42,16 +44,17 @@
 
 #ifdef BMP_SUPPORTED
 JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
-JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
+JMESSAGE(JERR_BMP_BADDEPTH, "Only 8-, 24-, and 32-bit BMP files are supported")
 JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
 JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
 JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
 JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
 JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
 JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
-JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
+JMESSAGE(JERR_BMP_OUTOFRANGE, "Numeric value out of range in BMP file")
+JMESSAGE(JTRC_BMP, "%ux%u %d-bit BMP image")
 JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
-JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
+JMESSAGE(JTRC_BMP_OS2, "%ux%u %d-bit OS2 BMP image")
 JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
 #endif /* BMP_SUPPORTED */
 
@@ -59,6 +62,7 @@
 JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
 JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
 JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
+JMESSAGE(JERR_GIF_EMPTY, "Empty GIF image")
 JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
 JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
 JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
@@ -75,31 +79,14 @@
 #ifdef PPM_SUPPORTED
 JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
 JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
-JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file")
 JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
+JMESSAGE(JERR_PPM_OUTOFRANGE, "Numeric value out of range in PPM file")
 JMESSAGE(JTRC_PGM, "%ux%u PGM image")
 JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
 JMESSAGE(JTRC_PPM, "%ux%u PPM image")
 JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
 #endif /* PPM_SUPPORTED */
 
-#ifdef RLE_SUPPORTED
-JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
-JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
-JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
-JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
-JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
-JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
-JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
-JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
-JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
-JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
-JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
-JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
-JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
-JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
-#endif /* RLE_SUPPORTED */
-
 #ifdef TARGA_SUPPORTED
 JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
 JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
diff --git a/src/third_party/libjpeg-turbo/cdjpeg.c b/src/third_party/libjpeg-turbo/cdjpeg.c
index e0e382d..5278c1d 100644
--- a/src/third_party/libjpeg-turbo/cdjpeg.c
+++ b/src/third_party/libjpeg-turbo/cdjpeg.c
@@ -3,8 +3,8 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * It was modified by The libjpeg-turbo Project to include only code relevant
- * to libjpeg-turbo.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -25,26 +25,37 @@
  * Optional progress monitor: display a percent-done figure on stderr.
  */
 
-#ifdef PROGRESS_REPORT
-
 METHODDEF(void)
 progress_monitor(j_common_ptr cinfo)
 {
   cd_progress_ptr prog = (cd_progress_ptr)cinfo->progress;
-  int total_passes = prog->pub.total_passes + prog->total_extra_passes;
-  int percent_done =
-    (int)(prog->pub.pass_counter * 100L / prog->pub.pass_limit);
 
-  if (percent_done != prog->percent_done) {
-    prog->percent_done = percent_done;
-    if (total_passes > 1) {
-      fprintf(stderr, "\rPass %d/%d: %3d%% ",
-              prog->pub.completed_passes + prog->completed_extra_passes + 1,
-              total_passes, percent_done);
-    } else {
-      fprintf(stderr, "\r %3d%% ", percent_done);
+  if (prog->max_scans != 0 && cinfo->is_decompressor) {
+    int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number;
+
+    if (scan_no > (int)prog->max_scans) {
+      fprintf(stderr, "Scan number %d exceeds maximum scans (%d)\n", scan_no,
+              prog->max_scans);
+      exit(EXIT_FAILURE);
     }
-    fflush(stderr);
+  }
+
+  if (prog->report) {
+    int total_passes = prog->pub.total_passes + prog->total_extra_passes;
+    int percent_done =
+      (int)(prog->pub.pass_counter * 100L / prog->pub.pass_limit);
+
+    if (percent_done != prog->percent_done) {
+      prog->percent_done = percent_done;
+      if (total_passes > 1) {
+        fprintf(stderr, "\rPass %d/%d: %3d%% ",
+                prog->pub.completed_passes + prog->completed_extra_passes + 1,
+                total_passes, percent_done);
+      } else {
+        fprintf(stderr, "\r %3d%% ", percent_done);
+      }
+      fflush(stderr);
+    }
   }
 }
 
@@ -57,6 +68,8 @@
     progress->pub.progress_monitor = progress_monitor;
     progress->completed_extra_passes = 0;
     progress->total_extra_passes = 0;
+    progress->max_scans = 0;
+    progress->report = FALSE;
     progress->percent_done = -1;
     cinfo->progress = &progress->pub;
   }
@@ -73,8 +86,6 @@
   }
 }
 
-#endif
-
 
 /*
  * Case-insensitive matching of possibly-abbreviated keyword switches.
diff --git a/src/third_party/libjpeg-turbo/cdjpeg.h b/src/third_party/libjpeg-turbo/cdjpeg.h
index c93f3ab..86e47c9 100644
--- a/src/third_party/libjpeg-turbo/cdjpeg.h
+++ b/src/third_party/libjpeg-turbo/cdjpeg.h
@@ -3,8 +3,9 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1997, Thomas G. Lane.
+ * Modified 2019 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2017, D. R. Commander.
+ * Copyright (C) 2017, 2019, 2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -31,10 +32,17 @@
   JDIMENSION (*get_pixel_rows) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
   void (*finish_input) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
 
+#if defined(STARBOARD)
   SbFile *input_file;
+#else
+  FILE *input_file;
+#endif
 
   JSAMPARRAY buffer;
   JDIMENSION buffer_height;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  JDIMENSION max_pixels;
+#endif
 };
 
 
@@ -56,15 +64,19 @@
   void (*finish_output) (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo);
   /* Re-calculate buffer dimensions based on output dimensions (for use with
      partial image decompression.)  If this is NULL, then the output format
-     does not support partial image decompression (BMP and RLE, in particular,
-     cannot support partial decompression because they use an inversion buffer
-     to write the image in bottom-up order.) */
+     does not support partial image decompression (BMP, in particular, cannot
+     support partial decompression because it uses an inversion buffer to write
+     the image in bottom-up order.) */
   void (*calc_buffer_dimensions) (j_decompress_ptr cinfo,
                                   djpeg_dest_ptr dinfo);
 
 
   /* Target file spec; filled in by djpeg.c after object is created. */
+#if defined(STARBOARD)
   SbFile *output_file;
+#else
+  FILE *output_file;
+#endif
 
   /* Output pixel-row buffer.  Created by module init or start_output.
    * Width is cinfo->output_width * cinfo->output_components;
@@ -87,6 +99,9 @@
   struct jpeg_progress_mgr pub; /* fields known to JPEG library */
   int completed_extra_passes;   /* extra passes completed */
   int total_extra_passes;       /* total extra */
+  JDIMENSION max_scans;         /* abort if the number of scans exceeds this
+                                   value and the value is non-zero */
+  boolean report;               /* whether or not to report progress */
   /* last printed percentage stored here to avoid multiple printouts */
   int percent_done;
 };
@@ -101,11 +116,9 @@
 EXTERN(djpeg_dest_ptr) jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
                                        boolean use_inversion_array);
 EXTERN(cjpeg_source_ptr) jinit_read_gif(j_compress_ptr cinfo);
-EXTERN(djpeg_dest_ptr) jinit_write_gif(j_decompress_ptr cinfo);
+EXTERN(djpeg_dest_ptr) jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw);
 EXTERN(cjpeg_source_ptr) jinit_read_ppm(j_compress_ptr cinfo);
 EXTERN(djpeg_dest_ptr) jinit_write_ppm(j_decompress_ptr cinfo);
-EXTERN(cjpeg_source_ptr) jinit_read_rle(j_compress_ptr cinfo);
-EXTERN(djpeg_dest_ptr) jinit_write_rle(j_decompress_ptr cinfo);
 EXTERN(cjpeg_source_ptr) jinit_read_targa(j_compress_ptr cinfo);
 EXTERN(djpeg_dest_ptr) jinit_write_targa(j_decompress_ptr cinfo);
 
@@ -121,17 +134,26 @@
 
 /* djpeg support routines (in rdcolmap.c) */
 
+#if defined(STARBOARD)
 EXTERN(void) read_color_map(j_decompress_ptr cinfo, SbFile *infile);
+#else
+EXTERN(void) read_color_map(j_decompress_ptr cinfo, FILE *infile);
+#endif
 
 /* common support routines (in cdjpeg.c) */
 
-EXTERN(void) enable_signal_catcher(j_common_ptr cinfo);
 EXTERN(void) start_progress_monitor(j_common_ptr cinfo,
                                     cd_progress_ptr progress);
 EXTERN(void) end_progress_monitor(j_common_ptr cinfo);
 EXTERN(boolean) keymatch(char *arg, const char *keyword, int minchars);
+
+#if defined(STARBOARD)
 EXTERN(SbFile *) read_stdin(void);
 EXTERN(SbFile *) write_stdout(void);
+#else
+EXTERN(FILE *) read_stdin(void);
+EXTERN(FILE *) write_stdout(void);
+#endif
 
 /* miscellaneous useful macros */
 
diff --git a/src/third_party/libjpeg-turbo/change.log b/src/third_party/libjpeg-turbo/change.log
index f090d77..e4d0ddc 100644
--- a/src/third_party/libjpeg-turbo/change.log
+++ b/src/third_party/libjpeg-turbo/change.log
@@ -6,6 +6,25 @@
 CHANGE LOG for Independent JPEG Group's JPEG software
 
 
+Version 9d  12-Jan-2020
+-----------------------
+
+Restore GIF read and write support from libjpeg version 6a.
+Thank to Wolfgang Werner (W.W.) Heinz for suggestion.
+
+Add jpegtran -drop option; add options to the crop extension and wipe
+to fill the extra area with content from the source image region,
+instead of gray out.
+
+
+Version 9c  14-Jan-2018
+-----------------------
+
+jpegtran: add an option to the -wipe switch to fill the region
+with the average of adjacent blocks, instead of gray out.
+Thank to Caitlyn Feddock and Maddie Ziegler for inspiration.
+
+
 Version 9b  17-Jan-2016
 -----------------------
 
@@ -13,6 +32,13 @@
 Thank to Michele Martone for suggestion.
 
 
+Version 9a  19-Jan-2014
+-----------------------
+
+Add jpegtran -wipe option and extension for -crop.
+Thank to Andrew Senior, David Clunie, and Josef Schmid for suggestion.
+
+
 Version 9  13-Jan-2013
 ----------------------
 
@@ -138,11 +164,6 @@
 
 Huffman tables are checked for validity much more carefully than before.
 
-To avoid the Unisys LZW patent, djpeg's GIF output capability has been
-changed to produce "uncompressed GIFs", and cjpeg's GIF input capability
-has been removed altogether.  We're not happy about it either, but there
-seems to be no good alternative.
-
 The configure script now supports building libjpeg as a shared library
 on many flavors of Unix (all the ones that GNU libtool knows how to
 build shared libraries for).  Use "./configure --enable-shared" to
diff --git a/src/third_party/libjpeg-turbo/cjpeg.1 b/src/third_party/libjpeg-turbo/cjpeg.1
index a3e47ba..569dc3f 100644
--- a/src/third_party/libjpeg-turbo/cjpeg.1
+++ b/src/third_party/libjpeg-turbo/cjpeg.1
@@ -1,4 +1,4 @@
-.TH CJPEG 1 "18 March 2017"
+.TH CJPEG 1 "4 November 2020"
 .SH NAME
 cjpeg \- compress an image file to a JPEG file
 .SH SYNOPSIS
@@ -16,8 +16,7 @@
 compresses the named image file, or the standard input if no file is
 named, and produces a JPEG/JFIF file on the standard output.
 The currently supported input file formats are: PPM (PBMPLUS color
-format), PGM (PBMPLUS grayscale format), BMP, Targa, and RLE (Utah Raster
-Toolkit format).  (RLE is supported only if the URT library is available.)
+format), PGM (PBMPLUS grayscale format), BMP, GIF, and Targa.
 .SH OPTIONS
 All switch names may be abbreviated; for example,
 .B \-grayscale
@@ -42,10 +41,10 @@
 .TP
 .B \-grayscale
 Create monochrome JPEG file from color input.  Be sure to use this switch when
-compressing a grayscale BMP file, because
+compressing a grayscale BMP or GIF file, because
 .B cjpeg
-isn't bright enough to notice whether a BMP file uses only shades of gray.
-By saying
+isn't bright enough to notice whether a BMP or GIF file uses only shades of
+gray.  By saying
 .BR \-grayscale,
 you'll get a smaller JPEG file that takes less time to process.
 .TP
@@ -161,31 +160,40 @@
 unable to view an arithmetic coded JPEG file at all.
 .TP
 .B \-dct int
-Use integer DCT method (default).
+Use accurate integer DCT method (default).
 .TP
 .B \-dct fast
-Use fast integer DCT (less accurate).
-In libjpeg-turbo, the fast method is generally about 5-15% faster than the int
-method when using the x86/x86-64 SIMD extensions (results may vary with other
-SIMD implementations, or when using libjpeg-turbo without SIMD extensions.)
+Use less accurate integer DCT method [legacy feature].
+When the Independent JPEG Group's software was first released in 1991, the
+compression time for a 1-megapixel JPEG image on a mainstream PC was measured
+in minutes.  Thus, the \fBfast\fR integer DCT algorithm provided noticeable
+performance benefits.  On modern CPUs running libjpeg-turbo, however, the
+compression time for a 1-megapixel JPEG image is measured in milliseconds, and
+thus the performance benefits of the \fBfast\fR algorithm are much less
+noticeable.  On modern x86/x86-64 CPUs that support AVX2 instructions, the
+\fBfast\fR and \fBint\fR methods have similar performance.  On other types of
+CPUs, the \fBfast\fR method is generally about 5-15% faster than the \fBint\fR
+method.
+
 For quality levels of 90 and below, there should be little or no perceptible
-difference between the two algorithms.  For quality levels above 90, however,
-the difference between the fast and the int methods becomes more pronounced.
-With quality=97, for instance, the fast method incurs generally about a 1-3 dB
-loss (in PSNR) relative to the int method, but this can be larger for some
-images.  Do not use the fast method with quality levels above 97.  The
-algorithm often degenerates at quality=98 and above and can actually produce a
-more lossy image than if lower quality levels had been used.  Also, in
-libjpeg-turbo, the fast method is not fully accelerated for quality levels
-above 97, so it will be slower than the int method.
+quality difference between the two algorithms.  For quality levels above 90,
+however, the difference between the \fBfast\fR and \fBint\fR methods becomes
+more pronounced.  With quality=97, for instance, the \fBfast\fR method incurs
+generally about a 1-3 dB loss in PSNR relative to the \fBint\fR method, but
+this can be larger for some images.  Do not use the \fBfast\fR method with
+quality levels above 97.  The algorithm often degenerates at quality=98 and
+above and can actually produce a more lossy image than if lower quality levels
+had been used.  Also, in libjpeg-turbo, the \fBfast\fR method is not fully
+accelerated for quality levels above 97, so it will be slower than the
+\fBint\fR method.
 .TP
 .B \-dct float
-Use floating-point DCT method.
-The float method is mainly a legacy feature.  It does not produce significantly
-more accurate results than the int method, and it is much slower.  The float
-method may also give different results on different machines due to varying
-roundoff behavior, whereas the integer methods should give the same results on
-all machines.
+Use floating-point DCT method [legacy feature].
+The \fBfloat\fR method does not produce significantly more accurate results
+than the \fBint\fR method, and it is much slower.  The \fBfloat\fR method may
+also give different results on different machines due to varying roundoff
+behavior, whereas the integer methods should give the same results on all
+machines.
 .TP
 .BI \-icc " file"
 Embed ICC color management profile contained in the specified file.
@@ -215,6 +223,9 @@
 way of testing the in-memory destination manager (jpeg_mem_dest()), but it is
 also useful for benchmarking, since it reduces the I/O overhead.
 .TP
+.BI \-report
+Report compression progress.
+.TP
 .B \-verbose
 Enable debug printout.  More
 .BR \-v 's
@@ -341,11 +352,6 @@
 relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
 features not present in libjpeg.
 .SH ISSUES
-Support for GIF input files was removed in cjpeg v6b due to concerns over
-the Unisys LZW patent.  Although this patent expired in 2006, cjpeg still
-lacks GIF support, for these historical reasons.  (Conversion of GIF files to
-JPEG is usually a bad idea anyway, since GIF is a 256-color format.)
-.PP
 Not all variants of BMP and Targa file formats are supported.
 .PP
 The
diff --git a/src/third_party/libjpeg-turbo/cjpeg.c b/src/third_party/libjpeg-turbo/cjpeg.c
index 07e7db1..66ac28f 100644
--- a/src/third_party/libjpeg-turbo/cjpeg.c
+++ b/src/third_party/libjpeg-turbo/cjpeg.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1998, Thomas G. Lane.
  * Modified 2003-2011 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2013-2014, 2017, D. R. Commander.
+ * Copyright (C) 2010, 2013-2014, 2017, 2019-2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -27,6 +27,9 @@
  * works regardless of which command line style is used.
  */
 
+#ifdef CJPEG_FUZZER
+#define JPEG_INTERNALS
+#endif
 #include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
 #include "jversion.h"           /* for version message */
 #include "jconfigint.h"
@@ -69,9 +72,9 @@
  *     2) assume we can push back more than one character (works in
  *        some C implementations, but unportable);
  *     3) provide our own buffering (breaks input readers that want to use
- *        stdio directly, such as the RLE library);
+ *        stdio directly);
  * or  4) don't put back the data, and modify the input_init methods to assume
- *        they start reading after the start of file (also breaks RLE library).
+ *        they start reading after the start of file.
  * #1 is attractive for MS-DOS but is untenable on Unix.
  *
  * The most portable solution for file types that can't be identified by their
@@ -117,10 +120,6 @@
   case 'P':
     return jinit_read_ppm(cinfo);
 #endif
-#ifdef RLE_SUPPORTED
-  case 'R':
-    return jinit_read_rle(cinfo);
-#endif
 #ifdef TARGA_SUPPORTED
   case 0x00:
     return jinit_read_targa(cinfo);
@@ -147,6 +146,46 @@
 static char *icc_filename;      /* for -icc switch */
 static char *outfilename;       /* for -outfile switch */
 boolean memdst;                 /* for -memdst switch */
+boolean report;                 /* for -report switch */
+
+
+#ifdef CJPEG_FUZZER
+
+#include <setjmp.h>
+
+struct my_error_mgr {
+  struct jpeg_error_mgr pub;
+  jmp_buf setjmp_buffer;
+};
+
+void my_error_exit(j_common_ptr cinfo)
+{
+  struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
+
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+static void my_emit_message(j_common_ptr cinfo, int msg_level)
+{
+  if (msg_level < 0)
+    cinfo->err->num_warnings++;
+}
+
+#define HANDLE_ERROR() { \
+  if (cinfo.global_state > CSTATE_START) { \
+    if (memdst && outbuffer) \
+      (*cinfo.dest->term_destination) (&cinfo); \
+    jpeg_abort_compress(&cinfo); \
+  } \
+  jpeg_destroy_compress(&cinfo); \
+  if (input_file != stdin && input_file != NULL) \
+    fclose(input_file); \
+  if (memdst) \
+    free(outbuffer); \
+  return EXIT_FAILURE; \
+}
+
+#endif
 
 
 LOCAL(void)
@@ -179,15 +218,15 @@
   fprintf(stderr, "  -arithmetic    Use arithmetic coding\n");
 #endif
 #ifdef DCT_ISLOW_SUPPORTED
-  fprintf(stderr, "  -dct int       Use integer DCT method%s\n",
+  fprintf(stderr, "  -dct int       Use accurate integer DCT method%s\n",
           (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
 #endif
 #ifdef DCT_IFAST_SUPPORTED
-  fprintf(stderr, "  -dct fast      Use fast integer DCT (less accurate)%s\n",
+  fprintf(stderr, "  -dct fast      Use less accurate integer DCT method [legacy feature]%s\n",
           (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
 #endif
 #ifdef DCT_FLOAT_SUPPORTED
-  fprintf(stderr, "  -dct float     Use floating-point DCT method%s\n",
+  fprintf(stderr, "  -dct float     Use floating-point DCT method [legacy feature]%s\n",
           (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
 #endif
   fprintf(stderr, "  -icc FILE      Embed ICC profile contained in FILE\n");
@@ -200,6 +239,7 @@
 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   fprintf(stderr, "  -memdst        Compress to memory instead of file (useful for benchmarking)\n");
 #endif
+  fprintf(stderr, "  -report        Report compression progress\n");
   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
   fprintf(stderr, "  -version       Print version information and exit\n");
   fprintf(stderr, "Switches for wizards:\n");
@@ -244,6 +284,7 @@
   icc_filename = NULL;
   outfilename = NULL;
   memdst = FALSE;
+  report = FALSE;
   cinfo->err->trace_level = 0;
 
   /* Scan command line options, adjust parameters */
@@ -395,6 +436,9 @@
       qtablefile = argv[argn];
       /* We postpone actually reading the file in case -quality comes later. */
 
+    } else if (keymatch(arg, "report", 3)) {
+      report = TRUE;
+
     } else if (keymatch(arg, "restart", 1)) {
       /* Restart interval in MCU rows (or in MCUs with 'b'). */
       long lval;
@@ -501,16 +545,23 @@
  */
 
 int
+#ifdef GTEST
+cjpeg(int argc, char **argv)
+#else
 main(int argc, char **argv)
+#endif
 {
   struct jpeg_compress_struct cinfo;
+#ifdef CJPEG_FUZZER
+  struct my_error_mgr myerr;
+  struct jpeg_error_mgr &jerr = myerr.pub;
+#else
   struct jpeg_error_mgr jerr;
-#ifdef PROGRESS_REPORT
-  struct cdjpeg_progress_mgr progress;
 #endif
+  struct cdjpeg_progress_mgr progress;
   int file_index;
   cjpeg_source_ptr src_mgr;
-  FILE *input_file;
+  FILE *input_file = NULL;
   FILE *icc_file;
   JOCTET *icc_profile = NULL;
   long icc_len = 0;
@@ -583,7 +634,7 @@
   if (file_index < argc) {
     if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else {
     /* default input file is stdin */
@@ -594,7 +645,7 @@
   if (outfilename != NULL) {
     if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else if (!memdst) {
     /* default output file is stdout */
@@ -604,37 +655,48 @@
   if (icc_filename != NULL) {
     if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if (fseek(icc_file, 0, SEEK_END) < 0 ||
         (icc_len = ftell(icc_file)) < 1 ||
         fseek(icc_file, 0, SEEK_SET) < 0) {
       fprintf(stderr, "%s: can't determine size of %s\n", progname,
               icc_filename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
       fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
       fclose(icc_file);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
       fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
               icc_filename);
       free(icc_profile);
       fclose(icc_file);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     fclose(icc_file);
   }
 
-#ifdef PROGRESS_REPORT
-  start_progress_monitor((j_common_ptr)&cinfo, &progress);
+#ifdef CJPEG_FUZZER
+  jerr.error_exit = my_error_exit;
+  jerr.emit_message = my_emit_message;
+  if (setjmp(myerr.setjmp_buffer))
+    HANDLE_ERROR()
 #endif
 
+  if (report) {
+    start_progress_monitor((j_common_ptr)&cinfo, &progress);
+    progress.report = report;
+  }
+
   /* Figure out the input file format, and set up to read it. */
   src_mgr = select_file_type(&cinfo, input_file);
   src_mgr->input_file = input_file;
+#ifdef CJPEG_FUZZER
+  src_mgr->max_pixels = 1048576;
+#endif
 
   /* Read the input file header to obtain file size & colorspace. */
   (*src_mgr->start_input) (&cinfo, src_mgr);
@@ -653,6 +715,11 @@
 #endif
     jpeg_stdio_dest(&cinfo, output_file);
 
+#ifdef CJPEG_FUZZER
+  if (setjmp(myerr.setjmp_buffer))
+    HANDLE_ERROR()
+#endif
+
   /* Start compressor */
   jpeg_start_compress(&cinfo, TRUE);
 
@@ -676,20 +743,18 @@
   if (output_file != stdout && output_file != NULL)
     fclose(output_file);
 
-#ifdef PROGRESS_REPORT
-  end_progress_monitor((j_common_ptr)&cinfo);
-#endif
+  if (report)
+    end_progress_monitor((j_common_ptr)&cinfo);
 
   if (memdst) {
+#ifndef CJPEG_FUZZER
     fprintf(stderr, "Compressed size:  %lu bytes\n", outsize);
-    if (outbuffer != NULL)
-      free(outbuffer);
+#endif
+    free(outbuffer);
   }
 
-  if (icc_profile != NULL)
-    free(icc_profile);
+  free(icc_profile);
 
   /* All done. */
-  exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
-  return 0;                     /* suppress no-return-value warnings */
+  return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
 }
diff --git a/src/third_party/libjpeg-turbo/cmakescripts/BuildPackages.cmake b/src/third_party/libjpeg-turbo/cmakescripts/BuildPackages.cmake
deleted file mode 100644
index 57f0672..0000000
--- a/src/third_party/libjpeg-turbo/cmakescripts/BuildPackages.cmake
+++ /dev/null
@@ -1,177 +0,0 @@
-# This file is included from the top-level CMakeLists.txt.  We just store it
-# here to avoid cluttering up that file.
-
-set(PKGNAME ${CMAKE_PROJECT_NAME} CACHE STRING
-  "Distribution package name (default: ${CMAKE_PROJECT_NAME})")
-set(PKGVENDOR "The ${CMAKE_PROJECT_NAME} Project" CACHE STRING
-  "Vendor name to be included in distribution package descriptions (default: The ${CMAKE_PROJECT_NAME} Project)")
-set(PKGURL "http://www.${CMAKE_PROJECT_NAME}.org" CACHE STRING
-  "URL of project web site to be included in distribution package descriptions (default: http://www.${CMAKE_PROJECT_NAME}.org)")
-set(PKGEMAIL "information@${CMAKE_PROJECT_NAME}.org" CACHE STRING
-  "E-mail of project maintainer to be included in distribution package descriptions (default: information@${CMAKE_PROJECT_NAME}.org")
-set(PKGID "com.${CMAKE_PROJECT_NAME}.${PKGNAME}" CACHE STRING
-  "Globally unique package identifier (reverse DNS notation) (default: com.${CMAKE_PROJECT_NAME}.${PKGNAME})")
-
-
-###############################################################################
-# Linux RPM and DEB
-###############################################################################
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-
-set(RPMARCH ${CMAKE_SYSTEM_PROCESSOR})
-if(CPU_TYPE STREQUAL "x86_64")
-  set(DEBARCH amd64)
-elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7*")
-  set(DEBARCH armhf)
-elseif(CPU_TYPE STREQUAL "arm64")
-  set(DEBARCH ${CPU_TYPE})
-elseif(CPU_TYPE STREQUAL "arm")
-  set(DEBARCH armel)
-elseif(CMAKE_SYSTEM_PROCESSOR_LC STREQUAL "ppc64le")
-  set(DEBARCH ppc64el)
-elseif(CPU_TYPE STREQUAL "powerpc" AND BITS EQUAL 32)
-  set(RPMARCH ppc)
-  set(DEBARCH ppc)
-else()
-  set(DEBARCH ${CMAKE_SYSTEM_PROCESSOR})
-endif()
-message(STATUS "RPM architecture = ${RPMARCH}, DEB architecture = ${DEBARCH}")
-
-# Re-set CMAKE_POSITION_INDEPENDENT_CODE so that the RPM spec file works
-# properly
-boolean_number(CMAKE_POSITION_INDEPENDENT_CODE)
-
-configure_file(release/makerpm.in pkgscripts/makerpm)
-configure_file(release/rpm.spec.in pkgscripts/rpm.spec @ONLY)
-
-add_custom_target(rpm sh pkgscripts/makerpm
-  SOURCES pkgscripts/makerpm)
-
-configure_file(release/makesrpm.in pkgscripts/makesrpm)
-
-add_custom_target(srpm sh pkgscripts/makesrpm
-  SOURCES pkgscripts/makesrpm
-  DEPENDS dist)
-
-configure_file(release/makedpkg.in pkgscripts/makedpkg)
-configure_file(release/deb-control.in pkgscripts/deb-control)
-
-add_custom_target(deb sh pkgscripts/makedpkg
-  SOURCES pkgscripts/makedpkg)
-
-endif() # Linux
-
-
-###############################################################################
-# Windows installer (NullSoft Installer)
-###############################################################################
-
-if(WIN32)
-
-if(MSVC)
-  set(INST_PLATFORM "Visual C++")
-  set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-vc)
-  set(INST_REG_NAME ${CMAKE_PROJECT_NAME})
-elseif(MINGW)
-  set(INST_PLATFORM GCC)
-  set(INST_NAME ${CMAKE_PROJECT_NAME}-${VERSION}-gcc)
-  set(INST_REG_NAME ${CMAKE_PROJECT_NAME}-gcc)
-  set(INST_DEFS -DGCC)
-endif()
-
-if(BITS EQUAL 64)
-  set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
-  set(INST_NAME ${INST_NAME}64)
-  set(INST_REG_NAME ${INST_DIR}64)
-  set(INST_DEFS ${INST_DEFS} -DWIN64)
-endif()
-
-if(WITH_JAVA)
-  set(INST_DEFS ${INST_DEFS} -DJAVA)
-endif()
-
-if(MSVC_IDE)
-  set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=${CMAKE_CFG_INTDIR}\\")
-else()
-  set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
-endif()
-
-string(REGEX REPLACE "/" "\\\\" INST_DIR ${CMAKE_INSTALL_PREFIX})
-
-configure_file(release/installer.nsi.in installer.nsi @ONLY)
-
-if(WITH_JAVA)
-  set(JAVA_DEPEND turbojpeg-java)
-endif()
-add_custom_target(installer
-  makensis -nocd ${INST_DEFS} installer.nsi
-  DEPENDS jpeg jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom
-    cjpeg djpeg jpegtran tjbench ${JAVA_DEPEND}
-  SOURCES installer.nsi)
-
-endif() # WIN32
-
-
-###############################################################################
-# Cygwin Package
-###############################################################################
-
-if(CYGWIN)
-
-configure_file(release/makecygwinpkg.in pkgscripts/makecygwinpkg)
-
-add_custom_target(cygwinpkg sh pkgscripts/makecygwinpkg)
-
-endif() # CYGWIN
-
-
-###############################################################################
-# Mac DMG
-###############################################################################
-
-if(APPLE)
-
-set(DEFAULT_OSX_32BIT_BUILD ${CMAKE_SOURCE_DIR}/osxx86)
-set(OSX_32BIT_BUILD ${DEFAULT_OSX_32BIT_BUILD} CACHE PATH
-  "Directory containing 32-bit (i386) Mac build to include in universal binaries (default: ${DEFAULT_OSX_32BIT_BUILD})")
-set(DEFAULT_IOS_ARMV7_BUILD ${CMAKE_SOURCE_DIR}/iosarmv7)
-set(IOS_ARMV7_BUILD ${DEFAULT_IOS_ARMV7_BUILD} CACHE PATH
-  "Directory containing ARMv7 iOS build to include in universal binaries (default: ${DEFAULT_IOS_ARMV7_BUILD})")
-set(DEFAULT_IOS_ARMV7S_BUILD ${CMAKE_SOURCE_DIR}/iosarmv7s)
-set(IOS_ARMV7S_BUILD ${DEFAULT_IOS_ARMV7S_BUILD} CACHE PATH
-  "Directory containing ARMv7s iOS build to include in universal binaries (default: ${DEFAULT_IOS_ARMV7S_BUILD})")
-set(DEFAULT_IOS_ARMV8_BUILD ${CMAKE_SOURCE_DIR}/iosarmv8)
-set(IOS_ARMV8_BUILD ${DEFAULT_IOS_ARMV8_BUILD} CACHE PATH
-  "Directory containing ARMv8 iOS build to include in universal binaries (default: ${DEFAULT_IOS_ARMV8_BUILD})")
-
-configure_file(release/makemacpkg.in pkgscripts/makemacpkg)
-configure_file(release/Distribution.xml.in pkgscripts/Distribution.xml)
-configure_file(release/uninstall.in pkgscripts/uninstall)
-
-add_custom_target(dmg sh pkgscripts/makemacpkg
-  SOURCES pkgscripts/makemacpkg)
-
-add_custom_target(udmg sh pkgscripts/makemacpkg universal
-  SOURCES pkgscripts/makemacpkg)
-
-endif() # APPLE
-
-
-###############################################################################
-# Generic
-###############################################################################
-
-add_custom_target(dist
-  COMMAND git archive --prefix=${CMAKE_PROJECT_NAME}-${VERSION}/ HEAD |
-    gzip > ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}.tar.gz
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-
-configure_file(release/maketarball.in pkgscripts/maketarball)
-
-add_custom_target(tarball sh pkgscripts/maketarball
-  SOURCES pkgscripts/maketarball)
-
-configure_file(release/libjpeg.pc.in pkgscripts/libjpeg.pc @ONLY)
-
-configure_file(release/libturbojpeg.pc.in pkgscripts/libturbojpeg.pc @ONLY)
diff --git a/src/third_party/libjpeg-turbo/cmakescripts/GNUInstallDirs.cmake b/src/third_party/libjpeg-turbo/cmakescripts/GNUInstallDirs.cmake
deleted file mode 100644
index ef564bb..0000000
--- a/src/third_party/libjpeg-turbo/cmakescripts/GNUInstallDirs.cmake
+++ /dev/null
@@ -1,416 +0,0 @@
-#.rst:
-# GNUInstallDirs
-# --------------
-#
-# Define GNU standard installation directories
-#
-# Provides install directory variables as defined by the
-# `GNU Coding Standards`_.
-#
-# .. _`GNU Coding Standards`: https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
-#
-# Result Variables
-# ^^^^^^^^^^^^^^^^
-#
-# Inclusion of this module defines the following variables:
-#
-# ``CMAKE_INSTALL_<dir>``
-#
-#   Destination for files of a given type.  This value may be passed to
-#   the ``DESTINATION`` options of :command:`install` commands for the
-#   corresponding file type.
-#
-# ``CMAKE_INSTALL_FULL_<dir>``
-#
-#   The absolute path generated from the corresponding ``CMAKE_INSTALL_<dir>``
-#   value.  If the value is not already an absolute path, an absolute path
-#   is constructed typically by prepending the value of the
-#   :variable:`CMAKE_INSTALL_PREFIX` variable.  However, there are some
-#   `special cases`_ as documented below.
-#
-# where ``<dir>`` is one of:
-#
-# ``BINDIR``
-#   user executables (``bin``)
-# ``SBINDIR``
-#   system admin executables (``sbin``)
-# ``LIBEXECDIR``
-#   program executables (``libexec``)
-# ``SYSCONFDIR``
-#   read-only single-machine data (``etc``)
-# ``SHAREDSTATEDIR``
-#   modifiable architecture-independent data (``com``)
-# ``LOCALSTATEDIR``
-#   modifiable single-machine data (``var``)
-# ``LIBDIR``
-#   object code libraries (``lib`` or ``lib64``
-#   or ``lib/<multiarch-tuple>`` on Debian)
-# ``INCLUDEDIR``
-#   C header files (``include``)
-# ``OLDINCLUDEDIR``
-#   C header files for non-gcc (``/usr/include``)
-# ``DATAROOTDIR``
-#   read-only architecture-independent data root (``share``)
-# ``DATADIR``
-#   read-only architecture-independent data (``DATAROOTDIR``)
-# ``INFODIR``
-#   info documentation (``DATAROOTDIR/info``)
-# ``LOCALEDIR``
-#   locale-dependent data (``DATAROOTDIR/locale``)
-# ``MANDIR``
-#   man documentation (``DATAROOTDIR/man``)
-# ``DOCDIR``
-#   documentation root (``DATAROOTDIR/doc/PROJECT_NAME``)
-#
-# If the includer does not define a value the above-shown default will be
-# used and the value will appear in the cache for editing by the user.
-#
-# Special Cases
-# ^^^^^^^^^^^^^
-#
-# The following values of :variable:`CMAKE_INSTALL_PREFIX` are special:
-#
-# ``/``
-#
-#   For ``<dir>`` other than the ``SYSCONFDIR`` and ``LOCALSTATEDIR``,
-#   the value of ``CMAKE_INSTALL_<dir>`` is prefixed with ``usr/`` if
-#   it is not user-specified as an absolute path.  For example, the
-#   ``INCLUDEDIR`` value ``include`` becomes ``usr/include``.
-#   This is required by the `GNU Coding Standards`_, which state:
-#
-#     When building the complete GNU system, the prefix will be empty
-#     and ``/usr`` will be a symbolic link to ``/``.
-#
-# ``/usr``
-#
-#   For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
-#   ``CMAKE_INSTALL_FULL_<dir>`` is computed by prepending just ``/``
-#   to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
-#   as an absolute path.  For example, the ``SYSCONFDIR`` value ``etc``
-#   becomes ``/etc``.  This is required by the `GNU Coding Standards`_.
-#
-# ``/opt/...``
-#
-#   For ``<dir>`` equal to ``SYSCONFDIR`` or ``LOCALSTATEDIR``, the
-#   ``CMAKE_INSTALL_FULL_<dir>`` is computed by *appending* the prefix
-#   to the value of ``CMAKE_INSTALL_<dir>`` if it is not user-specified
-#   as an absolute path.  For example, the ``SYSCONFDIR`` value ``etc``
-#   becomes ``/etc/opt/...``.  This is defined by the
-#   `Filesystem Hierarchy Standard`_.
-#
-# .. _`Filesystem Hierarchy Standard`: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
-#
-# Macros
-# ^^^^^^
-#
-# .. command:: GNUInstallDirs_get_absolute_install_dir
-#
-#   ::
-#
-#     GNUInstallDirs_get_absolute_install_dir(absvar var)
-#
-#   Set the given variable ``absvar`` to the absolute path contained
-#   within the variable ``var``.  This is to allow the computation of an
-#   absolute path, accounting for all the special cases documented
-#   above.  While this macro is used to compute the various
-#   ``CMAKE_INSTALL_FULL_<dir>`` variables, it is exposed publicly to
-#   allow users who create additional path variables to also compute
-#   absolute paths where necessary, using the same logic.
-
-#=============================================================================
-# Copyright 2016 D. R. Commander
-# Copyright 2016 Dmitry Marakasov
-# Copyright 2016 Roger Leigh
-# Copyright 2015 Alex Turbov
-# Copyright 2014 Rolf Eike Beer
-# Copyright 2014 Daniele E. Domenichelli
-# Copyright 2013 Dimitri John Ledkov
-# Copyright 2011 Alex Neundorf
-# Copyright 2011 Eric NOULARD
-# Copyright 2011, 2013-2015 Kitware, Inc.
-# Copyright 2011 Nikita Krupen'ko
-#
-# 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 names of Kitware, Inc., the Insight Software Consortium,
-#   nor the names of their 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.
-#=============================================================================
-
-# Installation directories
-#
-
-macro(GNUInstallDirs_set_install_dir var docstring)
-  # If CMAKE_INSTALL_PREFIX changes and CMAKE_INSTALL_*DIR is still set to the
-  # default value, then modify it accordingly.  This presumes that the default
-  # value may change based on the prefix.
-
-  set(_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var} "")
-  if(NOT DEFINED CMAKE_INSTALL_${var})
-    set(_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} 1 CACHE INTERNAL
-      "CMAKE_INSTALL_${var} has default value")
-  elseif(DEFINED _GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var} AND
-    NOT "${_GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var}}" STREQUAL
-      "${CMAKE_INSTALL_DEFAULT_${var}}" AND
-    _GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} AND
-    "${_GNUInstallDirs_CMAKE_INSTALL_LAST_${var}}" STREQUAL
-      "${CMAKE_INSTALL_${var}}")
-    set(_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var} "FORCE")
-  endif()
-
-  set(CMAKE_INSTALL_${var} "${CMAKE_INSTALL_DEFAULT_${var}}" CACHE PATH
-    "${docstring} (Default: ${CMAKE_INSTALL_DEFAULT_${var}})"
-    ${_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var}})
-
-  if(NOT "${CMAKE_INSTALL_${var}}" STREQUAL "${CMAKE_INSTALL_DEFAULT_${var}}")
-    unset(_GNUInstallDirs_CMAKE_INSTALL_DEFAULT_${var} CACHE)
-  endif()
-
-  # Save for next run
-  set(_GNUInstallDirs_CMAKE_INSTALL_LAST_${var} "${CMAKE_INSTALL_${var}}"
-    CACHE INTERNAL "CMAKE_INSTALL_${var} during last run")
-  set(_GNUInstallDirs_CMAKE_INSTALL_LAST_DEFAULT_${var}
-    "${CMAKE_INSTALL_DEFAULT_${var}}" CACHE INTERNAL
-    "CMAKE_INSTALL_DEFAULT_${var} during last run")
-endmacro()
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_BINDIR)
-  set(CMAKE_INSTALL_DEFAULT_BINDIR "bin")
-endif()
-GNUInstallDirs_set_install_dir(BINDIR
-  "Directory into which user executables should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SBINDIR)
-  set(CMAKE_INSTALL_DEFAULT_SBINDIR "sbin")
-endif()
-GNUInstallDirs_set_install_dir(SBINDIR
-  "Directory into which system admin executables should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LIBEXECDIR)
-  set(CMAKE_INSTALL_DEFAULT_LIBEXECDIR "libexec")
-endif()
-GNUInstallDirs_set_install_dir(LIBEXECDIR
-  "Directory under which executables run by other programs should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SYSCONFDIR)
-  set(CMAKE_INSTALL_DEFAULT_SYSCONFDIR "etc")
-endif()
-GNUInstallDirs_set_install_dir(SYSCONFDIR
-  "Directory into which machine-specific read-only ASCII data and configuration files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_SHAREDSTATEDIR)
-  set(CMAKE_INSTALL_DEFAULT_SHAREDSTATEDIR "com")
-endif()
-GNUInstallDirs_set_install_dir(SHAREDSTATEDIR
-  "Directory into which architecture-independent run-time-modifiable data files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LOCALSTATEDIR)
-  set(CMAKE_INSTALL_DEFAULT_LOCALSTATEDIR "var")
-endif()
-GNUInstallDirs_set_install_dir(LOCALSTATEDIR
-  "Directory into which machine-specific run-time-modifiable data files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LIBDIR)
-  set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib")
-  # Override this default 'lib' with 'lib64' iff:
-  #  - we are on Linux system but NOT cross-compiling
-  #  - we are NOT on debian
-  #  - we are on a 64 bits system
-  # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
-  # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if
-  # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu"
-  # and CMAKE_INSTALL_PREFIX is "/usr"
-  # See http://wiki.debian.org/Multiarch
-  if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
-      AND NOT CMAKE_CROSSCOMPILING)
-    if (EXISTS "/etc/debian_version") # is this a debian system ?
-      if(CMAKE_LIBRARY_ARCHITECTURE)
-        if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
-          set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib/${CMAKE_LIBRARY_ARCHITECTURE}")
-        endif()
-      endif()
-    else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
-      if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
-        message(AUTHOR_WARNING
-          "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
-          "Please enable at least one language before including GNUInstallDirs.")
-      else()
-        if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
-          set(CMAKE_INSTALL_DEFAULT_LIBDIR "lib64")
-        endif()
-      endif()
-    endif()
-  endif()
-endif()
-GNUInstallDirs_set_install_dir(LIBDIR
-  "Directory into which object files and object code libraries should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_INCLUDEDIR)
-  set(CMAKE_INSTALL_DEFAULT_INCLUDEDIR "include")
-endif()
-GNUInstallDirs_set_install_dir(INCLUDEDIR
-  "Directory into which C header files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_OLDINCLUDEDIR)
-  set(CMAKE_INSTALL_DEFAULT_OLDINCLUDEDIR "/usr/include")
-endif()
-GNUInstallDirs_set_install_dir(OLDINCLUDEDIR
-  PATH "Directory into which C header files for non-GCC compilers should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DATAROOTDIR)
-  set(CMAKE_INSTALL_DEFAULT_DATAROOTDIR "share")
-endif()
-GNUInstallDirs_set_install_dir(DATAROOTDIR
-  "The root of the directory tree for read-only architecture-independent data files")
-
-#-----------------------------------------------------------------------------
-# Values whose defaults are relative to DATAROOTDIR.  Store empty values in
-# the cache and store the defaults in local variables if the cache values are
-# not set explicitly.  This auto-updates the defaults as DATAROOTDIR changes.
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DATADIR)
-  set(CMAKE_INSTALL_DEFAULT_DATADIR "<CMAKE_INSTALL_DATAROOTDIR>")
-endif()
-GNUInstallDirs_set_install_dir(DATADIR
-  "The directory under which read-only architecture-independent data files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_INFODIR)
-  if(CMAKE_SYSTEM_NAME MATCHES "^(.*BSD|DragonFly)$")
-    set(CMAKE_INSTALL_DEFAULT_INFODIR "info")
-  else()
-    set(CMAKE_INSTALL_DEFAULT_INFODIR "<CMAKE_INSTALL_DATAROOTDIR>/info")
-  endif()
-endif()
-GNUInstallDirs_set_install_dir(INFODIR
-  "The directory into which info documentation files should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_MANDIR)
-  if(CMAKE_SYSTEM_NAME MATCHES "^(.*BSD|DragonFly)$")
-    set(CMAKE_INSTALL_DEFAULT_MANDIR "man")
-  else()
-    set(CMAKE_INSTALL_DEFAULT_MANDIR "<CMAKE_INSTALL_DATAROOTDIR>/man")
-  endif()
-endif()
-GNUInstallDirs_set_install_dir(MANDIR
-  "The directory under which man pages should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_LOCALEDIR)
-  set(CMAKE_INSTALL_DEFAULT_LOCALEDIR "<CMAKE_INSTALL_DATAROOTDIR>/locale")
-endif()
-GNUInstallDirs_set_install_dir(LOCALEDIR
-  "The directory under which locale-specific message catalogs should be installed")
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DOCDIR)
-  set(CMAKE_INSTALL_DEFAULT_DOCDIR "<CMAKE_INSTALL_DATAROOTDIR>/doc/${PROJECT_NAME}")
-endif()
-GNUInstallDirs_set_install_dir(DOCDIR
-  "The directory into which documentation files (other than info files) should be installed")
-
-#-----------------------------------------------------------------------------
-
-mark_as_advanced(
-  CMAKE_INSTALL_BINDIR
-  CMAKE_INSTALL_SBINDIR
-  CMAKE_INSTALL_LIBEXECDIR
-  CMAKE_INSTALL_SYSCONFDIR
-  CMAKE_INSTALL_SHAREDSTATEDIR
-  CMAKE_INSTALL_LOCALSTATEDIR
-  CMAKE_INSTALL_LIBDIR
-  CMAKE_INSTALL_INCLUDEDIR
-  CMAKE_INSTALL_OLDINCLUDEDIR
-  CMAKE_INSTALL_DATAROOTDIR
-  CMAKE_INSTALL_DATADIR
-  CMAKE_INSTALL_INFODIR
-  CMAKE_INSTALL_LOCALEDIR
-  CMAKE_INSTALL_MANDIR
-  CMAKE_INSTALL_DOCDIR
-  )
-
-macro(GNUInstallDirs_get_absolute_install_dir absvar var)
-  string(REGEX REPLACE "[<>]" "@" ${var} "${${var}}")
-  # Handle the specific case of an empty CMAKE_INSTALL_DATAROOTDIR
-  if(NOT CMAKE_INSTALL_DATAROOTDIR AND
-    ${var} MATCHES "\@CMAKE_INSTALL_DATAROOTDIR\@/")
-    string(CONFIGURE "${${var}}" ${var} @ONLY)
-    string(REGEX REPLACE "^/" "" ${var} "${${var}}")
-  else()
-    string(CONFIGURE "${${var}}" ${var} @ONLY)
-  endif()
-  if(NOT IS_ABSOLUTE "${${var}}")
-    # Handle special cases:
-    # - CMAKE_INSTALL_PREFIX == /
-    # - CMAKE_INSTALL_PREFIX == /usr
-    # - CMAKE_INSTALL_PREFIX == /opt/...
-    if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
-        set(${absvar} "/${${var}}")
-      else()
-        if (NOT "${${var}}" MATCHES "^usr/")
-          set(${var} "usr/${${var}}")
-        endif()
-        set(${absvar} "/${${var}}")
-      endif()
-    elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/?$")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
-        set(${absvar} "/${${var}}")
-      else()
-        set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
-      endif()
-    elseif("${CMAKE_INSTALL_PREFIX}" MATCHES "^/opt/.*")
-      if("${dir}" STREQUAL "SYSCONFDIR" OR "${dir}" STREQUAL "LOCALSTATEDIR")
-        set(${absvar} "/${${var}}${CMAKE_INSTALL_PREFIX}")
-      else()
-        set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
-      endif()
-    else()
-      set(${absvar} "${CMAKE_INSTALL_PREFIX}/${${var}}")
-    endif()
-  else()
-    set(${absvar} "${${var}}")
-  endif()
-  string(REGEX REPLACE "/$" "" ${absvar} "${${absvar}}")
-endmacro()
-
-# Result directories
-#
-foreach(dir
-    BINDIR
-    SBINDIR
-    LIBEXECDIR
-    SYSCONFDIR
-    SHAREDSTATEDIR
-    LOCALSTATEDIR
-    LIBDIR
-    INCLUDEDIR
-    OLDINCLUDEDIR
-    DATAROOTDIR
-    DATADIR
-    INFODIR
-    LOCALEDIR
-    MANDIR
-    DOCDIR
-    )
-  GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_${dir} CMAKE_INSTALL_${dir})
-endforeach()
diff --git a/src/third_party/libjpeg-turbo/cmakescripts/cmake_uninstall.cmake.in b/src/third_party/libjpeg-turbo/cmakescripts/cmake_uninstall.cmake.in
deleted file mode 100644
index 6726a0d..0000000
--- a/src/third_party/libjpeg-turbo/cmakescripts/cmake_uninstall.cmake.in
+++ /dev/null
@@ -1,24 +0,0 @@
-# This code is from the CMake FAQ
-
-if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
-  message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"")
-endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
-
-file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
-string(REGEX REPLACE "\n" ";" files "${files}")
-list(REVERSE files)
-foreach (file ${files})
-  message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
-    if (EXISTS "$ENV{DESTDIR}${file}")
-      execute_process(
-        COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
-        OUTPUT_VARIABLE rm_out
-        RESULT_VARIABLE rm_retval
-      )
-    if(NOT ${rm_retval} EQUAL 0)
-      message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
-    endif (NOT ${rm_retval} EQUAL 0)
-  else (EXISTS "$ENV{DESTDIR}${file}")
-    message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
-  endif (EXISTS "$ENV{DESTDIR}${file}")
-endforeach(file)
diff --git a/src/third_party/libjpeg-turbo/cmakescripts/testclean.cmake b/src/third_party/libjpeg-turbo/cmakescripts/testclean.cmake
deleted file mode 100644
index fc3fc25..0000000
--- a/src/third_party/libjpeg-turbo/cmakescripts/testclean.cmake
+++ /dev/null
@@ -1,41 +0,0 @@
-file(GLOB FILES
-  testout*
-  *_GRAY_*.bmp
-  *_GRAY_*.png
-  *_GRAY_*.ppm
-  *_GRAY_*.jpg
-  *_GRAY.yuv
-  *_420_*.bmp
-  *_420_*.png
-  *_420_*.ppm
-  *_420_*.jpg
-  *_420.yuv
-  *_422_*.bmp
-  *_422_*.png
-  *_422_*.ppm
-  *_422_*.jpg
-  *_422.yuv
-  *_444_*.bmp
-  *_444_*.png
-  *_444_*.ppm
-  *_444_*.jpg
-  *_444.yuv
-  *_440_*.bmp
-  *_440_*.png
-  *_440_*.ppm
-  *_440_*.jpg
-  *_440.yuv
-  *_411_*.bmp
-  *_411_*.png
-  *_411_*.ppm
-  *_411_*.jpg
-  *_411.yuv
-  tjbenchtest*.log
-  tjexampletest*.log)
-
-if(NOT FILES STREQUAL "")
-  message(STATUS "Removing test files")
-  file(REMOVE ${FILES})
-else()
-  message(STATUS "No files to remove")
-endif()
diff --git a/src/third_party/libjpeg-turbo/croptest.in b/src/third_party/libjpeg-turbo/croptest.in
new file mode 100644
index 0000000..7e3c293
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/croptest.in
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+set -u
+set -e
+trap onexit INT
+trap onexit TERM
+trap onexit EXIT
+
+onexit()
+{
+	if [ -d $OUTDIR ]; then
+		rm -rf $OUTDIR
+	fi
+}
+
+runme()
+{
+	echo \*\*\* $*
+	$*
+}
+
+IMAGE=vgl_6548_0026a.bmp
+WIDTH=128
+HEIGHT=95
+IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages
+OUTDIR=`mktemp -d /tmp/__croptest_output.XXXXXX`
+EXEDIR=@CMAKE_CURRENT_BINARY_DIR@
+
+if [ -d $OUTDIR ]; then
+	rm -rf $OUTDIR
+fi
+mkdir -p $OUTDIR
+
+exec >$EXEDIR/croptest.log
+
+echo "============================================================"
+echo "$IMAGE ($WIDTH x $HEIGHT)"
+echo "============================================================"
+echo
+
+for PROGARG in "" -progressive; do
+
+	cp $IMGDIR/$IMAGE $OUTDIR
+	basename=`basename $IMAGE .bmp`
+	echo "------------------------------------------------------------"
+	echo "Generating test images"
+	echo "------------------------------------------------------------"
+	echo
+	runme $EXEDIR/cjpeg $PROGARG -grayscale -outfile $OUTDIR/${basename}_GRAY.jpg $IMGDIR/${basename}.bmp
+	runme $EXEDIR/cjpeg $PROGARG -sample 2x2 -outfile $OUTDIR/${basename}_420.jpg $IMGDIR/${basename}.bmp
+	runme $EXEDIR/cjpeg $PROGARG -sample 2x1 -outfile $OUTDIR/${basename}_422.jpg $IMGDIR/${basename}.bmp
+	runme $EXEDIR/cjpeg $PROGARG -sample 1x2 -outfile $OUTDIR/${basename}_440.jpg $IMGDIR/${basename}.bmp
+	runme $EXEDIR/cjpeg $PROGARG -sample 1x1 -outfile $OUTDIR/${basename}_444.jpg $IMGDIR/${basename}.bmp
+	echo
+
+	for NSARG in "" -nosmooth; do
+
+		for COLORSARG in "" "-colors 256 -dither none -onepass"; do
+
+			for Y in {0..16}; do
+
+				for H in {1..16}; do
+
+					X=$(( (Y*16)%128 ))
+					W=$(( WIDTH-X-7 ))
+					if [ $Y -le 15 ]; then
+						CROPSPEC="${W}x${H}+${X}+${Y}"
+					else
+						Y2=$(( HEIGHT-H ));
+						CROPSPEC="${W}x${H}+${X}+${Y2}"
+					fi
+
+					echo "------------------------------------------------------------"
+					echo $PROGARG $NSARG $COLORSARG -crop $CROPSPEC
+					echo "------------------------------------------------------------"
+					echo
+					for samp in GRAY 420 422 440 444; do
+						$EXEDIR/djpeg $NSARG $COLORSARG -rgb -outfile $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}.jpg
+						convert -crop $CROPSPEC $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}_ref.ppm
+						runme $EXEDIR/djpeg $NSARG $COLORSARG -crop $CROPSPEC -rgb -outfile $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}.jpg
+						runme cmp $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}_ref.ppm
+					done
+					echo
+
+				done
+
+			done
+
+		done
+
+	done
+
+done
+
+echo SUCCESS!
diff --git a/src/third_party/libjpeg-turbo/djpeg.1 b/src/third_party/libjpeg-turbo/djpeg.1
index e4204b2..31431b9 100644
--- a/src/third_party/libjpeg-turbo/djpeg.1
+++ b/src/third_party/libjpeg-turbo/djpeg.1
@@ -1,4 +1,4 @@
-.TH DJPEG 1 "13 November 2017"
+.TH DJPEG 1 "4 November 2020"
 .SH NAME
 djpeg \- decompress a JPEG file to an image file
 .SH SYNOPSIS
@@ -15,8 +15,7 @@
 .B djpeg
 decompresses the named JPEG file, or the standard input if no file is named,
 and produces an image file on the standard output.  PBMPLUS (PPM/PGM), BMP,
-GIF, Targa, or RLE (Utah Raster Toolkit) output format can be selected.
-(RLE is supported only if the URT library is available.)
+GIF, or Targa output format can be selected.
 .SH OPTIONS
 All switch names may be abbreviated; for example,
 .B \-grayscale
@@ -81,9 +80,20 @@
 format is emitted.
 .TP
 .B \-gif
-Select GIF output format.  Since GIF does not support more than 256 colors,
+Select GIF output format (LZW-compressed).  Since GIF does not support more
+than 256 colors,
 .B \-colors 256
-is assumed (unless you specify a smaller number of colors).
+is assumed (unless you specify a smaller number of colors).  If you specify
+.BR \-fast,
+the default number of colors is 216.
+.TP
+.B \-gif0
+Select GIF output format (uncompressed).  Since GIF does not support more than
+256 colors,
+.B \-colors 256
+is assumed (unless you specify a smaller number of colors).  If you specify
+.BR \-fast,
+the default number of colors is 216.
 .TP
 .B \-os2
 Select BMP output format (OS/2 1.x flavor).  8-bit colormapped format is
@@ -100,9 +110,6 @@
 .B \-grayscale
 is specified; otherwise PPM is emitted.
 .TP
-.B \-rle
-Select RLE output format.  (Requires URT library.)
-.TP
 .B \-targa
 Select Targa output format.  Grayscale format is emitted if the JPEG file is
 grayscale or if
@@ -114,32 +121,40 @@
 Switches for advanced users:
 .TP
 .B \-dct int
-Use integer DCT method (default).
+Use accurate integer DCT method (default).
 .TP
 .B \-dct fast
-Use fast integer DCT (less accurate).
-In libjpeg-turbo, the fast method is generally about 5-15% faster than the int
-method when using the x86/x86-64 SIMD extensions (results may vary with other
-SIMD implementations, or when using libjpeg-turbo without SIMD extensions.)  If
-the JPEG image was compressed using a quality level of 85 or below, then there
-should be little or no perceptible difference between the two algorithms.  When
-decompressing images that were compressed using quality levels above 85,
-however, the difference between the fast and int methods becomes more
-pronounced.  With images compressed using quality=97, for instance, the fast
-method incurs generally about a 4-6 dB loss (in PSNR) relative to the int
-method, but this can be larger for some images.  If you can avoid it, do not
-use the fast method when decompressing images that were compressed using
-quality levels above 97.  The algorithm often degenerates for such images and
-can actually produce a more lossy output image than if the JPEG image had been
-compressed using lower quality levels.
+Use less accurate integer DCT method [legacy feature].
+When the Independent JPEG Group's software was first released in 1991, the
+decompression time for a 1-megapixel JPEG image on a mainstream PC was measured
+in minutes.  Thus, the \fBfast\fR integer DCT algorithm provided noticeable
+performance benefits.  On modern CPUs running libjpeg-turbo, however, the
+decompression time for a 1-megapixel JPEG image is measured in milliseconds,
+and thus the performance benefits of the \fBfast\fR algorithm are much less
+noticeable.  On modern x86/x86-64 CPUs that support AVX2 instructions, the
+\fBfast\fR and \fBint\fR methods have similar performance.  On other types of
+CPUs, the \fBfast\fR method is generally about 5-15% faster than the \fBint\fR
+method.
+
+If the JPEG image was compressed using a quality level of 85 or below, then
+there should be little or no perceptible quality difference between the two
+algorithms.  When decompressing images that were compressed using quality
+levels above 85, however, the difference between the \fBfast\fR and \fBint\fR
+methods becomes more pronounced.  With images compressed using quality=97, for
+instance, the \fBfast\fR method incurs generally about a 4-6 dB loss in PSNR
+relative to the \fBint\fR method, but this can be larger for some images.  If
+you can avoid it, do not use the \fBfast\fR method when decompressing images
+that were compressed using quality levels above 97.  The algorithm often
+degenerates for such images and can actually produce a more lossy output image
+than if the JPEG image had been compressed using lower quality levels.
 .TP
 .B \-dct float
-Use floating-point DCT method.
-The float method is mainly a legacy feature.  It does not produce significantly
-more accurate results than the int method, and it is much slower.  The float
-method may also give different results on different machines due to varying
-roundoff behavior, whereas the integer methods should give the same results on
-all machines.
+Use floating-point DCT method [legacy feature].
+The \fBfloat\fR method does not produce significantly more accurate results
+than the \fBint\fR method, and it is much slower.  The \fBfloat\fR method may
+also give different results on different machines due to varying roundoff
+behavior, whereas the integer methods should give the same results on all
+machines.
 .TP
 .B \-dither fs
 Use Floyd-Steinberg dithering in color quantization.
@@ -190,6 +205,19 @@
 .B \-max 4m
 selects 4000000 bytes.  If more space is needed, an error will occur.
 .TP
+.BI \-maxscans " N"
+Abort if the JPEG image contains more than
+.I N
+scans.  This feature demonstrates a method by which applications can guard
+against denial-of-service attacks instigated by specially-crafted malformed
+JPEG images containing numerous scans with missing image data or image data
+consisting only of "EOB runs" (a feature of progressive JPEG images that allows
+potentially hundreds of thousands of adjoining zero-value pixels to be
+represented using only a few bytes.)  Attempting to decompress such malformed
+JPEG images can cause excessive CPU activity, since the decompressor must fully
+process each scan (even if the scan is corrupt) before it can proceed to the
+next scan.
+.TP
 .BI \-outfile " name"
 Send output image to the named file, not to standard output.
 .TP
@@ -197,6 +225,9 @@
 Load input file into memory before decompressing.  This feature was implemented
 mainly as a way of testing the in-memory source manager (jpeg_mem_src().)
 .TP
+.BI \-report
+Report decompression progress.
+.TP
 .BI \-skip " Y0,Y1"
 Decompress all rows of the JPEG image except those between Y0 and Y1
 (inclusive.)  Note that if decompression scaling is being used, then Y0 and Y1
@@ -210,6 +241,12 @@
 scaled image dimensions.  Currently this option only works with the
 PBMPLUS (PPM/PGM), GIF, and Targa output formats.
 .TP
+.BI \-strict
+Treat all warnings as fatal.  This feature also demonstrates a method by which
+applications can guard against attacks instigated by specially-crafted
+malformed JPEG images.  Enabling this option will cause the decompressor to
+abort if the JPEG image contains incomplete or corrupt image data.
+.TP
 .B \-verbose
 Enable debug printout.  More
 .BR \-v 's
@@ -253,12 +290,6 @@
 .B \-dither none
 may give acceptable results in two-pass mode, but is seldom tolerable in
 one-pass mode.
-.PP
-If you are fortunate enough to have very fast floating point hardware,
-\fB\-dct float\fR may be even faster than \fB\-dct fast\fR.  But on most
-machines \fB\-dct float\fR is slower than \fB\-dct int\fR; in this case it is
-not worth using, because its theoretical accuracy advantage is too small to be
-significant in practice.
 .SH ENVIRONMENT
 .TP
 .B JPEGMEM
@@ -287,10 +318,3 @@
 This file was modified by The libjpeg-turbo Project to include only information
 relevant to libjpeg-turbo, to wordsmith certain sections, and to describe
 features not present in libjpeg.
-.SH ISSUES
-Support for compressed GIF output files was removed in djpeg v6b due to
-concerns over the Unisys LZW patent.  Although this patent expired in 2006,
-djpeg still lacks compressed GIF support, for these historical reasons.
-(Conversion of JPEG files to GIF is usually a bad idea anyway, since GIF is a
-256-color format.)  The uncompressed GIF files that djpeg generates are larger
-than they should be, but they are readable by standard GIF decoders.
diff --git a/src/third_party/libjpeg-turbo/djpeg.c b/src/third_party/libjpeg-turbo/djpeg.c
index 920e90d..cc2eb9d 100644
--- a/src/third_party/libjpeg-turbo/djpeg.c
+++ b/src/third_party/libjpeg-turbo/djpeg.c
@@ -3,9 +3,9 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * Modified 2013 by Guido Vollbeding.
+ * Modified 2013-2019 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010-2011, 2013-2017, D. R. Commander.
+ * Copyright (C) 2010-2011, 2013-2017, 2019-2020, D. R. Commander.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -68,10 +68,10 @@
 
 typedef enum {
   FMT_BMP,                      /* BMP format (Windows flavor) */
-  FMT_GIF,                      /* GIF format */
+  FMT_GIF,                      /* GIF format (LZW-compressed) */
+  FMT_GIF0,                     /* GIF format (uncompressed) */
   FMT_OS2,                      /* BMP format (OS/2 flavor) */
   FMT_PPM,                      /* PPM/PGM (PBMPLUS formats) */
-  FMT_RLE,                      /* RLE format */
   FMT_TARGA,                    /* Targa format */
   FMT_TIFF                      /* TIFF format */
 } IMAGE_FORMATS;
@@ -94,11 +94,14 @@
 
 static const char *progname;    /* program name for error messages */
 static char *icc_filename;      /* for -icc switch */
+static JDIMENSION max_scans;    /* for -maxscans switch */
 static char *outfilename;       /* for -outfile switch */
-boolean memsrc;                 /* for -memsrc switch */
+static boolean memsrc;          /* for -memsrc switch */
+static boolean report;          /* for -report switch */
 boolean skip, crop;
 JDIMENSION skip_start, skip_end;
 JDIMENSION crop_x, crop_y, crop_width, crop_height;
+static boolean strict;          /* for -strict switch */
 #define INPUT_BUF_SIZE  4096
 
 
@@ -127,8 +130,10 @@
           (DEFAULT_FMT == FMT_BMP ? " (default)" : ""));
 #endif
 #ifdef GIF_SUPPORTED
-  fprintf(stderr, "  -gif           Select GIF output format%s\n",
+  fprintf(stderr, "  -gif           Select GIF output format (LZW-compressed)%s\n",
           (DEFAULT_FMT == FMT_GIF ? " (default)" : ""));
+  fprintf(stderr, "  -gif0          Select GIF output format (uncompressed)%s\n",
+          (DEFAULT_FMT == FMT_GIF0 ? " (default)" : ""));
 #endif
 #ifdef BMP_SUPPORTED
   fprintf(stderr, "  -os2           Select BMP output format (OS/2 style)%s\n",
@@ -138,25 +143,21 @@
   fprintf(stderr, "  -pnm           Select PBMPLUS (PPM/PGM) output format%s\n",
           (DEFAULT_FMT == FMT_PPM ? " (default)" : ""));
 #endif
-#ifdef RLE_SUPPORTED
-  fprintf(stderr, "  -rle           Select Utah RLE output format%s\n",
-          (DEFAULT_FMT == FMT_RLE ? " (default)" : ""));
-#endif
 #ifdef TARGA_SUPPORTED
   fprintf(stderr, "  -targa         Select Targa output format%s\n",
           (DEFAULT_FMT == FMT_TARGA ? " (default)" : ""));
 #endif
   fprintf(stderr, "Switches for advanced users:\n");
 #ifdef DCT_ISLOW_SUPPORTED
-  fprintf(stderr, "  -dct int       Use integer DCT method%s\n",
+  fprintf(stderr, "  -dct int       Use accurate integer DCT method%s\n",
           (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
 #endif
 #ifdef DCT_IFAST_SUPPORTED
-  fprintf(stderr, "  -dct fast      Use fast integer DCT (less accurate)%s\n",
+  fprintf(stderr, "  -dct fast      Use less accurate integer DCT method [legacy feature]%s\n",
           (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
 #endif
 #ifdef DCT_FLOAT_SUPPORTED
-  fprintf(stderr, "  -dct float     Use floating-point DCT method%s\n",
+  fprintf(stderr, "  -dct float     Use floating-point DCT method [legacy feature]%s\n",
           (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
 #endif
   fprintf(stderr, "  -dither fs     Use F-S dithering (default)\n");
@@ -171,14 +172,16 @@
   fprintf(stderr, "  -onepass       Use 1-pass quantization (fast, low quality)\n");
 #endif
   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
+  fprintf(stderr, "  -maxscans N    Maximum number of scans to allow in input file\n");
   fprintf(stderr, "  -outfile name  Specify name for output file\n");
 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   fprintf(stderr, "  -memsrc        Load input file into memory before decompressing\n");
 #endif
-
+  fprintf(stderr, "  -report        Report decompression progress\n");
   fprintf(stderr, "  -skip Y0,Y1    Decompress all rows except those between Y0 and Y1 (inclusive)\n");
   fprintf(stderr, "  -crop WxH+X+Y  Decompress only a rectangular subregion of the image\n");
   fprintf(stderr, "                 [requires PBMPLUS (PPM/PGM), GIF, or Targa output format]\n");
+  fprintf(stderr, "  -strict        Treat all warnings as fatal\n");
   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
   fprintf(stderr, "  -version       Print version information and exit\n");
   exit(EXIT_FAILURE);
@@ -203,10 +206,13 @@
   /* Set up default JPEG parameters. */
   requested_fmt = DEFAULT_FMT;  /* set default output file format */
   icc_filename = NULL;
+  max_scans = 0;
   outfilename = NULL;
   memsrc = FALSE;
+  report = FALSE;
   skip = FALSE;
   crop = FALSE;
+  strict = FALSE;
   cinfo->err->trace_level = 0;
 
   /* Scan command line options, adjust parameters */
@@ -224,7 +230,7 @@
     arg++;                      /* advance past switch marker character */
 
     if (keymatch(arg, "bmp", 1)) {
-      /* BMP output format. */
+      /* BMP output format (Windows flavor). */
       requested_fmt = FMT_BMP;
 
     } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) ||
@@ -295,9 +301,13 @@
       cinfo->do_fancy_upsampling = FALSE;
 
     } else if (keymatch(arg, "gif", 1)) {
-      /* GIF output format. */
+      /* GIF output format (LZW-compressed). */
       requested_fmt = FMT_GIF;
 
+    } else if (keymatch(arg, "gif0", 4)) {
+      /* GIF output format (uncompressed). */
+      requested_fmt = FMT_GIF0;
+
     } else if (keymatch(arg, "grayscale", 2) ||
                keymatch(arg, "greyscale", 2)) {
       /* Force monochrome output. */
@@ -351,6 +361,12 @@
         lval *= 1000L;
       cinfo->mem->max_memory_to_use = lval * 1000L;
 
+    } else if (keymatch(arg, "maxscans", 4)) {
+      if (++argn >= argc)       /* advance to next argument */
+        usage();
+      if (sscanf(argv[argn], "%u", &max_scans) != 1)
+        usage();
+
     } else if (keymatch(arg, "nosmooth", 3)) {
       /* Suppress fancy upsampling */
       cinfo->do_fancy_upsampling = FALSE;
@@ -383,9 +399,8 @@
       /* PPM/PGM output format. */
       requested_fmt = FMT_PPM;
 
-    } else if (keymatch(arg, "rle", 1)) {
-      /* RLE output format. */
-      requested_fmt = FMT_RLE;
+    } else if (keymatch(arg, "report", 2)) {
+      report = TRUE;
 
     } else if (keymatch(arg, "scale", 2)) {
       /* Scale the output image by a fraction M/N. */
@@ -413,6 +428,9 @@
         usage();
       crop = TRUE;
 
+    } else if (keymatch(arg, "strict", 2)) {
+      strict = TRUE;
+
     } else if (keymatch(arg, "targa", 1)) {
       /* Targa output format. */
       requested_fmt = FMT_TARGA;
@@ -444,7 +462,7 @@
       ERREXIT(cinfo, JERR_CANT_SUSPEND);
   }
   datasrc->bytes_in_buffer--;
-  return GETJOCTET(*datasrc->next_input_byte++);
+  return *datasrc->next_input_byte++;
 }
 
 
@@ -499,24 +517,41 @@
 }
 
 
+METHODDEF(void)
+my_emit_message(j_common_ptr cinfo, int msg_level)
+{
+  if (msg_level < 0) {
+    /* Treat warning as fatal */
+    cinfo->err->error_exit(cinfo);
+  } else {
+    if (cinfo->err->trace_level >= msg_level)
+      cinfo->err->output_message(cinfo);
+  }
+}
+
+
 /*
  * The main program.
  */
 
 int
+#ifdef GTEST
+djpeg(int argc, char **argv)
+#else
 main(int argc, char **argv)
+#endif
 {
   struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
-#ifdef PROGRESS_REPORT
   struct cdjpeg_progress_mgr progress;
-#endif
   int file_index;
   djpeg_dest_ptr dest_mgr = NULL;
   FILE *input_file;
   FILE *output_file;
   unsigned char *inbuffer = NULL;
+#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   unsigned long insize = 0;
+#endif
   JDIMENSION num_scanlines;
 
   /* On Mac, fetch a command line. */
@@ -555,6 +590,9 @@
 
   file_index = parse_switches(&cinfo, argc, argv, 0, FALSE);
 
+  if (strict)
+    jerr.emit_message = my_emit_message;
+
 #ifdef TWO_FILE_COMMANDLINE
   /* Must have either -outfile switch or explicit output file name */
   if (outfilename == NULL) {
@@ -583,7 +621,7 @@
   if (file_index < argc) {
     if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else {
     /* default input file is stdin */
@@ -594,16 +632,18 @@
   if (outfilename != NULL) {
     if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else {
     /* default output file is stdout */
     output_file = write_stdout();
   }
 
-#ifdef PROGRESS_REPORT
-  start_progress_monitor((j_common_ptr)&cinfo, &progress);
-#endif
+  if (report || max_scans != 0) {
+    start_progress_monitor((j_common_ptr)&cinfo, &progress);
+    progress.report = report;
+    progress.max_scans = max_scans;
+  }
 
   /* Specify data source for decompression */
 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
@@ -613,7 +653,7 @@
       inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
       if (inbuffer == NULL) {
         fprintf(stderr, "%s: memory allocation failure\n", progname);
-        exit(EXIT_FAILURE);
+        return EXIT_FAILURE;
       }
       nbytes = JFREAD(input_file, &inbuffer[insize], INPUT_BUF_SIZE);
       if (nbytes < INPUT_BUF_SIZE && ferror(input_file)) {
@@ -651,7 +691,10 @@
 #endif
 #ifdef GIF_SUPPORTED
   case FMT_GIF:
-    dest_mgr = jinit_write_gif(&cinfo);
+    dest_mgr = jinit_write_gif(&cinfo, TRUE);
+    break;
+  case FMT_GIF0:
+    dest_mgr = jinit_write_gif(&cinfo, FALSE);
     break;
 #endif
 #ifdef PPM_SUPPORTED
@@ -659,11 +702,6 @@
     dest_mgr = jinit_write_ppm(&cinfo);
     break;
 #endif
-#ifdef RLE_SUPPORTED
-  case FMT_RLE:
-    dest_mgr = jinit_write_rle(&cinfo);
-    break;
-#endif
 #ifdef TARGA_SUPPORTED
   case FMT_TARGA:
     dest_mgr = jinit_write_targa(&cinfo);
@@ -689,7 +727,7 @@
     if (skip_end > cinfo.output_height - 1) {
       fprintf(stderr, "%s: skip region exceeds image height %d\n", progname,
               cinfo.output_height);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
 
     /* Write output file header.  This is a hack to ensure that the destination
@@ -706,7 +744,12 @@
                                           dest_mgr->buffer_height);
       (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
     }
-    jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1);
+    if ((tmp = jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1)) !=
+        skip_end - skip_start + 1) {
+      fprintf(stderr, "%s: jpeg_skip_scanlines() returned %d rather than %d\n",
+              progname, tmp, skip_end - skip_start + 1);
+      return EXIT_FAILURE;
+    }
     while (cinfo.output_scanline < cinfo.output_height) {
       num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
                                           dest_mgr->buffer_height);
@@ -724,7 +767,7 @@
         crop_y + crop_height > cinfo.output_height) {
       fprintf(stderr, "%s: crop dimensions exceed image dimensions %d x %d\n",
               progname, cinfo.output_width, cinfo.output_height);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
 
     jpeg_crop_scanline(&cinfo, &crop_x, &crop_width);
@@ -742,13 +785,24 @@
     cinfo.output_height = tmp;
 
     /* Process data */
-    jpeg_skip_scanlines(&cinfo, crop_y);
+    if ((tmp = jpeg_skip_scanlines(&cinfo, crop_y)) != crop_y) {
+      fprintf(stderr, "%s: jpeg_skip_scanlines() returned %d rather than %d\n",
+              progname, tmp, crop_y);
+      return EXIT_FAILURE;
+    }
     while (cinfo.output_scanline < crop_y + crop_height) {
       num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer,
                                           dest_mgr->buffer_height);
       (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
     }
-    jpeg_skip_scanlines(&cinfo, cinfo.output_height - crop_y - crop_height);
+    if ((tmp =
+         jpeg_skip_scanlines(&cinfo,
+                             cinfo.output_height - crop_y - crop_height)) !=
+        cinfo.output_height - crop_y - crop_height) {
+      fprintf(stderr, "%s: jpeg_skip_scanlines() returned %d rather than %d\n",
+              progname, tmp, cinfo.output_height - crop_y - crop_height);
+      return EXIT_FAILURE;
+    }
 
   /* Normal full-image decompress */
   } else {
@@ -763,12 +817,11 @@
     }
   }
 
-#ifdef PROGRESS_REPORT
   /* Hack: count final pass as done in case finish_output does an extra pass.
    * The library won't have updated completed_passes.
    */
-  progress.pub.completed_passes = progress.pub.total_passes;
-#endif
+  if (report || max_scans != 0)
+    progress.pub.completed_passes = progress.pub.total_passes;
 
   if (icc_filename != NULL) {
     FILE *icc_file;
@@ -777,7 +830,7 @@
 
     if ((icc_file = fopen(icc_filename, WRITE_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if (jpeg_read_icc_profile(&cinfo, &icc_profile, &icc_len)) {
       if (fwrite(icc_profile, icc_len, 1, icc_file) < 1) {
@@ -785,7 +838,7 @@
                 icc_filename);
         free(icc_profile);
         fclose(icc_file);
-        exit(EXIT_FAILURE);
+        return EXIT_FAILURE;
       }
       free(icc_profile);
       fclose(icc_file);
@@ -807,14 +860,12 @@
   if (output_file != stdout)
     fclose(output_file);
 
-#ifdef PROGRESS_REPORT
-  end_progress_monitor((j_common_ptr)&cinfo);
-#endif
+  if (report || max_scans != 0)
+    end_progress_monitor((j_common_ptr)&cinfo);
 
-  if (memsrc && inbuffer != NULL)
+  if (memsrc)
     free(inbuffer);
 
   /* All done. */
-  exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
-  return 0;                     /* suppress no-return-value warnings */
+  return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
 }
diff --git a/src/third_party/libjpeg-turbo/doc/html/annotated.html b/src/third_party/libjpeg-turbo/doc/html/annotated.html
deleted file mode 100644
index 50286d2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/annotated.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Data Structures</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="headertitle">
-<div class="title">Data Structures</div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock">Here are the data structures with brief descriptions:</div><div class="directory">
-<table class="directory">
-<tr id="row_0_" class="even"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjregion.html" target="_self">tjregion</a></td><td class="desc">Cropping region</td></tr>
-<tr id="row_1_"><td class="entry"><img src="ftv2node.png" alt="o" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjscalingfactor.html" target="_self">tjscalingfactor</a></td><td class="desc">Scaling factor</td></tr>
-<tr id="row_2_" class="even"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><img src="ftv2cl.png" alt="C" width="24" height="22" /><a class="el" href="structtjtransform.html" target="_self">tjtransform</a></td><td class="desc">Lossless transform</td></tr>
-</table>
-</div><!-- directory -->
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/bc_s.png b/src/third_party/libjpeg-turbo/doc/html/bc_s.png
deleted file mode 100644
index 224b29a..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/bc_s.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/bdwn.png b/src/third_party/libjpeg-turbo/doc/html/bdwn.png
deleted file mode 100644
index 940a0b9..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/bdwn.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/classes.html b/src/third_party/libjpeg-turbo/doc/html/classes.html
deleted file mode 100644
index 41a2811..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/classes.html
+++ /dev/null
@@ -1,106 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Data Structure Index</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li class="current"><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="headertitle">
-<div class="title">Data Structure Index</div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="qindex"><a class="qindex" href="#letter_T">T</a></div>
-<table style="margin: 10px; white-space: nowrap;" align="center" width="95%" border="0" cellspacing="0" cellpadding="0">
-<tr><td rowspan="2" valign="bottom"><a name="letter_T"></a><table border="0" cellspacing="0" cellpadding="0"><tr><td><div class="ah">&#160;&#160;T&#160;&#160;</div></td></tr></table>
-</td><td valign="top"><a class="el" href="structtjscalingfactor.html">tjscalingfactor</a>&#160;&#160;&#160;</td><td valign="top"><a class="el" href="structtjtransform.html">tjtransform</a>&#160;&#160;&#160;</td><td></td></tr>
-<tr><td></td><td></td><td></td></tr>
-<tr><td valign="top"><a class="el" href="structtjregion.html">tjregion</a>&#160;&#160;&#160;</td><td></td><td></td><td></td></tr>
-<tr><td></td><td></td><td></td><td></td></tr>
-</table>
-<div class="qindex"><a class="qindex" href="#letter_T">T</a></div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/closed.png b/src/third_party/libjpeg-turbo/doc/html/closed.png
deleted file mode 100644
index 98cc2c9..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/closed.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/doxygen-extra.css b/src/third_party/libjpeg-turbo/doc/html/doxygen-extra.css
deleted file mode 100644
index f1bd4c2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/doxygen-extra.css
+++ /dev/null
@@ -1,3 +0,0 @@
-code {
-	color: #4665A2;
-}
diff --git a/src/third_party/libjpeg-turbo/doc/html/doxygen.css b/src/third_party/libjpeg-turbo/doc/html/doxygen.css
deleted file mode 100644
index dabaff2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/doxygen.css
+++ /dev/null
@@ -1,1184 +0,0 @@
-/* The standard CSS for doxygen 1.8.3.1 */
-
-body, table, div, p, dl {
-	font: 400 14px/19px Roboto,sans-serif;
-}
-
-/* @group Heading Levels */
-
-h1.groupheader {
-	font-size: 150%;
-}
-
-.title {
-	font-size: 150%;
-	font-weight: bold;
-	margin: 10px 2px;
-}
-
-h2.groupheader {
-	border-bottom: 1px solid #879ECB;
-	color: #354C7B;
-	font-size: 150%;
-	font-weight: normal;
-	margin-top: 1.75em;
-	padding-top: 8px;
-	padding-bottom: 4px;
-	width: 100%;
-}
-
-h3.groupheader {
-	font-size: 100%;
-}
-
-h1, h2, h3, h4, h5, h6 {
-	-webkit-transition: text-shadow 0.5s linear;
-	-moz-transition: text-shadow 0.5s linear;
-	-ms-transition: text-shadow 0.5s linear;
-	-o-transition: text-shadow 0.5s linear;
-	transition: text-shadow 0.5s linear;
-	margin-right: 15px;
-}
-
-h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
-	text-shadow: 0 0 15px cyan;
-}
-
-dt {
-	font-weight: bold;
-}
-
-div.multicol {
-	-moz-column-gap: 1em;
-	-webkit-column-gap: 1em;
-	-moz-column-count: 3;
-	-webkit-column-count: 3;
-}
-
-p.startli, p.startdd, p.starttd {
-	margin-top: 2px;
-}
-
-p.endli {
-	margin-bottom: 0px;
-}
-
-p.enddd {
-	margin-bottom: 4px;
-}
-
-p.endtd {
-	margin-bottom: 2px;
-}
-
-/* @end */
-
-caption {
-	font-weight: bold;
-}
-
-span.legend {
-        font-size: 70%;
-        text-align: center;
-}
-
-h3.version {
-        font-size: 90%;
-        text-align: center;
-}
-
-div.qindex, div.navtab{
-	background-color: #EBEFF6;
-	border: 1px solid #A3B4D7;
-	text-align: center;
-}
-
-div.qindex, div.navpath {
-	width: 100%;
-	line-height: 140%;
-}
-
-div.navtab {
-	margin-right: 15px;
-}
-
-/* @group Link Styling */
-
-a {
-	color: #3D578C;
-	font-weight: normal;
-	text-decoration: none;
-}
-
-.contents a:visited {
-	color: #4665A2;
-}
-
-a:hover {
-	text-decoration: underline;
-}
-
-a.qindex {
-	font-weight: bold;
-}
-
-a.qindexHL {
-	font-weight: bold;
-	background-color: #9CAFD4;
-	color: #ffffff;
-	border: 1px double #869DCA;
-}
-
-.contents a.qindexHL:visited {
-        color: #ffffff;
-}
-
-a.el {
-	font-weight: bold;
-}
-
-a.elRef {
-}
-
-a.code, a.code:visited {
-	color: #4665A2; 
-}
-
-a.codeRef, a.codeRef:visited {
-	color: #4665A2; 
-}
-
-/* @end */
-
-dl.el {
-	margin-left: -1cm;
-}
-
-pre.fragment {
-        border: 1px solid #C4CFE5;
-        background-color: #FBFCFD;
-        padding: 4px 6px;
-        margin: 4px 8px 4px 2px;
-        overflow: auto;
-        word-wrap: break-word;
-        font-size:  9pt;
-        line-height: 125%;
-        font-family: monospace, fixed;
-        font-size: 105%;
-}
-
-div.fragment {
-        padding: 4px;
-        margin: 4px;
-	background-color: #FBFCFD;
-	border: 1px solid #C4CFE5;
-}
-
-div.line {
-	font-family: monospace, fixed;
-        font-size: 13px;
-	min-height: 13px;
-	line-height: 1.0;
-	text-wrap: unrestricted;
-	white-space: -moz-pre-wrap; /* Moz */
-	white-space: -pre-wrap;     /* Opera 4-6 */
-	white-space: -o-pre-wrap;   /* Opera 7 */
-	white-space: pre-wrap;      /* CSS3  */
-	word-wrap: break-word;      /* IE 5.5+ */
-	text-indent: -53px;
-	padding-left: 53px;
-	padding-bottom: 0px;
-	margin: 0px;
-	-webkit-transition-property: background-color, box-shadow;
-	-webkit-transition-duration: 0.5s;
-	-moz-transition-property: background-color, box-shadow;
-	-moz-transition-duration: 0.5s;
-	-ms-transition-property: background-color, box-shadow;
-	-ms-transition-duration: 0.5s;
-	-o-transition-property: background-color, box-shadow;
-	-o-transition-duration: 0.5s;
-	transition-property: background-color, box-shadow;
-	transition-duration: 0.5s;
-}
-
-div.line.glow {
-	background-color: cyan;
-	box-shadow: 0 0 10px cyan;
-}
-
-
-span.lineno {
-	padding-right: 4px;
-	text-align: right;
-	border-right: 2px solid #0F0;
-	background-color: #E8E8E8;
-        white-space: pre;
-}
-span.lineno a {
-	background-color: #D8D8D8;
-}
-
-span.lineno a:hover {
-	background-color: #C8C8C8;
-}
-
-div.ah {
-	background-color: black;
-	font-weight: bold;
-	color: #ffffff;
-	margin-bottom: 3px;
-	margin-top: 3px;
-	padding: 0.2em;
-	border: solid thin #333;
-	border-radius: 0.5em;
-	-webkit-border-radius: .5em;
-	-moz-border-radius: .5em;
-	box-shadow: 2px 2px 3px #999;
-	-webkit-box-shadow: 2px 2px 3px #999;
-	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
-	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
-}
-
-div.groupHeader {
-	margin-left: 16px;
-	margin-top: 12px;
-	font-weight: bold;
-}
-
-div.groupText {
-	margin-left: 16px;
-	font-style: italic;
-}
-
-body {
-	background-color: white;
-	color: black;
-        margin: 0;
-}
-
-div.contents {
-	margin-top: 10px;
-	margin-left: 12px;
-	margin-right: 8px;
-}
-
-td.indexkey {
-	background-color: #EBEFF6;
-	font-weight: bold;
-	border: 1px solid #C4CFE5;
-	margin: 2px 0px 2px 0;
-	padding: 2px 10px;
-        white-space: nowrap;
-        vertical-align: top;
-}
-
-td.indexvalue {
-	background-color: #EBEFF6;
-	border: 1px solid #C4CFE5;
-	padding: 2px 10px;
-	margin: 2px 0px;
-}
-
-tr.memlist {
-	background-color: #EEF1F7;
-}
-
-p.formulaDsp {
-	text-align: center;
-}
-
-img.formulaDsp {
-	
-}
-
-img.formulaInl {
-	vertical-align: middle;
-}
-
-div.center {
-	text-align: center;
-        margin-top: 0px;
-        margin-bottom: 0px;
-        padding: 0px;
-}
-
-div.center img {
-	border: 0px;
-}
-
-address.footer {
-	text-align: right;
-	padding-right: 12px;
-}
-
-img.footer {
-	border: 0px;
-	vertical-align: middle;
-}
-
-/* @group Code Colorization */
-
-span.keyword {
-	color: #008000
-}
-
-span.keywordtype {
-	color: #604020
-}
-
-span.keywordflow {
-	color: #e08000
-}
-
-span.comment {
-	color: #800000
-}
-
-span.preprocessor {
-	color: #806020
-}
-
-span.stringliteral {
-	color: #002080
-}
-
-span.charliteral {
-	color: #008080
-}
-
-span.vhdldigit { 
-	color: #ff00ff 
-}
-
-span.vhdlchar { 
-	color: #000000 
-}
-
-span.vhdlkeyword { 
-	color: #700070 
-}
-
-span.vhdllogic { 
-	color: #ff0000 
-}
-
-blockquote {
-        background-color: #F7F8FB;
-        border-left: 2px solid #9CAFD4;
-        margin: 0 24px 0 4px;
-        padding: 0 12px 0 16px;
-}
-
-/* @end */
-
-/*
-.search {
-	color: #003399;
-	font-weight: bold;
-}
-
-form.search {
-	margin-bottom: 0px;
-	margin-top: 0px;
-}
-
-input.search {
-	font-size: 75%;
-	color: #000080;
-	font-weight: normal;
-	background-color: #e8eef2;
-}
-*/
-
-td.tiny {
-	font-size: 75%;
-}
-
-.dirtab {
-	padding: 4px;
-	border-collapse: collapse;
-	border: 1px solid #A3B4D7;
-}
-
-th.dirtab {
-	background: #EBEFF6;
-	font-weight: bold;
-}
-
-hr {
-	height: 0px;
-	border: none;
-	border-top: 1px solid #4A6AAA;
-}
-
-hr.footer {
-	height: 1px;
-}
-
-/* @group Member Descriptions */
-
-table.memberdecls {
-	border-spacing: 0px;
-	padding: 0px;
-}
-
-.memberdecls td, .fieldtable tr {
-	-webkit-transition-property: background-color, box-shadow;
-	-webkit-transition-duration: 0.5s;
-	-moz-transition-property: background-color, box-shadow;
-	-moz-transition-duration: 0.5s;
-	-ms-transition-property: background-color, box-shadow;
-	-ms-transition-duration: 0.5s;
-	-o-transition-property: background-color, box-shadow;
-	-o-transition-duration: 0.5s;
-	transition-property: background-color, box-shadow;
-	transition-duration: 0.5s;
-}
-
-.memberdecls td.glow, .fieldtable tr.glow {
-	background-color: cyan;
-	box-shadow: 0 0 15px cyan;
-}
-
-.mdescLeft, .mdescRight,
-.memItemLeft, .memItemRight,
-.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
-	background-color: #F9FAFC;
-	border: none;
-	margin: 4px;
-	padding: 1px 0 0 8px;
-}
-
-.mdescLeft, .mdescRight {
-	padding: 0px 8px 4px 8px;
-	color: #555;
-}
-
-.memSeparator {
-        border-bottom: 1px solid #DEE4F0;
-        line-height: 1px;
-        margin: 0px;
-        padding: 0px;
-}
-
-.memItemLeft, .memTemplItemLeft {
-        white-space: nowrap;
-}
-
-.memItemRight {
-	width: 100%;
-}
-
-.memTemplParams {
-	color: #4665A2;
-        white-space: nowrap;
-	font-size: 80%;
-}
-
-/* @end */
-
-/* @group Member Details */
-
-/* Styles for detailed member documentation */
-
-.memtemplate {
-	font-size: 80%;
-	color: #4665A2;
-	font-weight: normal;
-	margin-left: 9px;
-}
-
-.memnav {
-	background-color: #EBEFF6;
-	border: 1px solid #A3B4D7;
-	text-align: center;
-	margin: 2px;
-	margin-right: 15px;
-	padding: 2px;
-}
-
-.mempage {
-	width: 100%;
-}
-
-.memitem {
-	padding: 0;
-	margin-bottom: 10px;
-	margin-right: 5px;
-        -webkit-transition: box-shadow 0.5s linear;
-        -moz-transition: box-shadow 0.5s linear;
-        -ms-transition: box-shadow 0.5s linear;
-        -o-transition: box-shadow 0.5s linear;
-        transition: box-shadow 0.5s linear;
-        display: table !important;
-        width: 100%;
-}
-
-.memitem.glow {
-         box-shadow: 0 0 15px cyan;
-}
-
-.memname {
-        font-weight: bold;
-        margin-left: 6px;
-}
-
-.memname td {
-	vertical-align: bottom;
-}
-
-.memproto, dl.reflist dt {
-        border-top: 1px solid #A8B8D9;
-        border-left: 1px solid #A8B8D9;
-        border-right: 1px solid #A8B8D9;
-        padding: 6px 0px 6px 0px;
-        color: #253555;
-        font-weight: bold;
-        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
-        background-image:url('nav_f.png');
-        background-repeat:repeat-x;
-        background-color: #E2E8F2;
-        /* opera specific markup */
-        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-        border-top-right-radius: 4px;
-        border-top-left-radius: 4px;
-        /* firefox specific markup */
-        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
-        -moz-border-radius-topright: 4px;
-        -moz-border-radius-topleft: 4px;
-        /* webkit specific markup */
-        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-        -webkit-border-top-right-radius: 4px;
-        -webkit-border-top-left-radius: 4px;
-
-}
-
-.memdoc, dl.reflist dd {
-        border-bottom: 1px solid #A8B8D9;      
-        border-left: 1px solid #A8B8D9;      
-        border-right: 1px solid #A8B8D9; 
-        padding: 6px 10px 2px 10px;
-        background-color: #FBFCFD;
-        border-top-width: 0;
-        background-image:url('nav_g.png');
-        background-repeat:repeat-x;
-        background-color: #FFFFFF;
-        /* opera specific markup */
-        border-bottom-left-radius: 4px;
-        border-bottom-right-radius: 4px;
-        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-        /* firefox specific markup */
-        -moz-border-radius-bottomleft: 4px;
-        -moz-border-radius-bottomright: 4px;
-        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
-        /* webkit specific markup */
-        -webkit-border-bottom-left-radius: 4px;
-        -webkit-border-bottom-right-radius: 4px;
-        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-}
-
-dl.reflist dt {
-        padding: 5px;
-}
-
-dl.reflist dd {
-        margin: 0px 0px 10px 0px;
-        padding: 5px;
-}
-
-.paramkey {
-	text-align: right;
-}
-
-.paramtype {
-	white-space: nowrap;
-}
-
-.paramname {
-	color: #602020;
-	white-space: nowrap;
-}
-.paramname em {
-	font-style: normal;
-}
-.paramname code {
-        line-height: 14px;
-}
-
-.params, .retval, .exception, .tparams {
-        margin-left: 0px;
-        padding-left: 0px;
-}       
-
-.params .paramname, .retval .paramname {
-        font-weight: bold;
-        vertical-align: top;
-}
-        
-.params .paramtype {
-        font-style: italic;
-        vertical-align: top;
-}       
-        
-.params .paramdir {
-        font-family: "courier new",courier,monospace;
-        vertical-align: top;
-}
-
-table.mlabels {
-	border-spacing: 0px;
-}
-
-td.mlabels-left {
-	width: 100%;
-	padding: 0px;
-}
-
-td.mlabels-right {
-	vertical-align: bottom;
-	padding: 0px;
-	white-space: nowrap;
-}
-
-span.mlabels {
-        margin-left: 8px;
-}
-
-span.mlabel {
-        background-color: #728DC1;
-        border-top:1px solid #5373B4;
-        border-left:1px solid #5373B4;
-        border-right:1px solid #C4CFE5;
-        border-bottom:1px solid #C4CFE5;
-	text-shadow: none;
-	color: white;
-	margin-right: 4px;
-	padding: 2px 3px;
-	border-radius: 3px;
-	font-size: 7pt;
-	white-space: nowrap;
-	vertical-align: middle;
-}
-
-
-
-/* @end */
-
-/* these are for tree view when not used as main index */
-
-div.directory {
-        margin: 10px 0px;
-        border-top: 1px solid #A8B8D9;
-        border-bottom: 1px solid #A8B8D9;
-        width: 100%;
-}
-
-.directory table {
-        border-collapse:collapse;
-}
-
-.directory td {
-        margin: 0px;
-        padding: 0px;
-	vertical-align: top;
-}
-
-.directory td.entry {
-        white-space: nowrap;
-        padding-right: 6px;
-}
-
-.directory td.entry a {
-        outline:none;
-}
-
-.directory td.entry a img {
-        border: none;
-}
-
-.directory td.desc {
-        width: 100%;
-        padding-left: 6px;
-	padding-right: 6px;
-	padding-top: 3px;
-	border-left: 1px solid rgba(0,0,0,0.05);
-}
-
-.directory tr.even {
-	padding-left: 6px;
-	background-color: #F7F8FB;
-}
-
-.directory img {
-	vertical-align: -30%;
-}
-
-.directory .levels {
-        white-space: nowrap;
-        width: 100%;
-        text-align: right;
-        font-size: 9pt;
-}
-
-.directory .levels span {
-        cursor: pointer;
-        padding-left: 2px;
-        padding-right: 2px;
-	color: #3D578C;
-}
-
-div.dynheader {
-        margin-top: 8px;
-	-webkit-touch-callout: none;
-	-webkit-user-select: none;
-	-khtml-user-select: none;
-	-moz-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-address {
-	font-style: normal;
-	color: #2A3D61;
-}
-
-table.doxtable {
-	border-collapse:collapse;
-        margin-top: 4px;
-        margin-bottom: 4px;
-}
-
-table.doxtable td, table.doxtable th {
-	border: 1px solid #2D4068;
-	padding: 3px 7px 2px;
-}
-
-table.doxtable th {
-	background-color: #374F7F;
-	color: #FFFFFF;
-	font-size: 110%;
-	padding-bottom: 4px;
-	padding-top: 5px;
-}
-
-table.fieldtable {
-        /*width: 100%;*/
-        margin-bottom: 10px;
-        border: 1px solid #A8B8D9;
-        border-spacing: 0px;
-        -moz-border-radius: 4px;
-        -webkit-border-radius: 4px;
-        border-radius: 4px;
-        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
-        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
-        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
-}
-
-.fieldtable td, .fieldtable th {
-        padding: 3px 7px 2px;
-}
-
-.fieldtable td.fieldtype, .fieldtable td.fieldname {
-        white-space: nowrap;
-        border-right: 1px solid #A8B8D9;
-        border-bottom: 1px solid #A8B8D9;
-        vertical-align: top;
-}
-
-.fieldtable td.fieldname {
-        padding-top: 5px;
-}
-
-.fieldtable td.fielddoc {
-        border-bottom: 1px solid #A8B8D9;
-        /*width: 100%;*/
-}
-
-.fieldtable td.fielddoc p:first-child {
-        margin-top: 2px;
-}       
-        
-.fieldtable td.fielddoc p:last-child {
-        margin-bottom: 2px;
-}
-
-.fieldtable tr:last-child td {
-        border-bottom: none;
-}
-
-.fieldtable th {
-        background-image:url('nav_f.png');
-        background-repeat:repeat-x;
-        background-color: #E2E8F2;
-        font-size: 90%;
-        color: #253555;
-        padding-bottom: 4px;
-        padding-top: 5px;
-        text-align:left;
-        -moz-border-radius-topleft: 4px;
-        -moz-border-radius-topright: 4px;
-        -webkit-border-top-left-radius: 4px;
-        -webkit-border-top-right-radius: 4px;
-        border-top-left-radius: 4px;
-        border-top-right-radius: 4px;
-        border-bottom: 1px solid #A8B8D9;
-}
-
-
-.tabsearch {
-	top: 0px;
-	left: 10px;
-	height: 36px;
-	background-image: url('tab_b.png');
-	z-index: 101;
-	overflow: hidden;
-	font-size: 13px;
-}
-
-.navpath ul
-{
-	font-size: 11px;
-	background-image:url('tab_b.png');
-	background-repeat:repeat-x;
-	background-position: 0 -5px;
-	height:30px;
-	line-height:30px;
-	color:#8AA0CC;
-	border:solid 1px #C2CDE4;
-	overflow:hidden;
-	margin:0px;
-	padding:0px;
-}
-
-.navpath li
-{
-	list-style-type:none;
-	float:left;
-	padding-left:10px;
-	padding-right:15px;
-	background-image:url('bc_s.png');
-	background-repeat:no-repeat;
-	background-position:right;
-	color:#364D7C;
-}
-
-.navpath li.navelem a
-{
-	height:32px;
-	display:block;
-	text-decoration: none;
-	outline: none;
-	color: #283A5D;
-	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
-	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
-	text-decoration: none;        
-}
-
-.navpath li.navelem a:hover
-{
-	color:#6884BD;
-}
-
-.navpath li.footer
-{
-        list-style-type:none;
-        float:right;
-        padding-left:10px;
-        padding-right:15px;
-        background-image:none;
-        background-repeat:no-repeat;
-        background-position:right;
-        color:#364D7C;
-        font-size: 8pt;
-}
-
-
-div.summary
-{
-	float: right;
-	font-size: 8pt;
-	padding-right: 5px;
-	width: 50%;
-	text-align: right;
-}       
-
-div.summary a
-{
-	white-space: nowrap;
-}
-
-div.ingroups
-{
-	font-size: 8pt;
-	width: 50%;
-	text-align: left;
-}
-
-div.ingroups a
-{
-	white-space: nowrap;
-}
-
-div.header
-{
-        background-image:url('nav_h.png');
-        background-repeat:repeat-x;
-	background-color: #F9FAFC;
-	margin:  0px;
-	border-bottom: 1px solid #C4CFE5;
-}
-
-div.headertitle
-{
-	padding: 5px 5px 5px 10px;
-}
-
-dl
-{
-        padding: 0 0 0 10px;
-}
-
-/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */
-dl.section
-{
-	margin-left: 0px;
-	padding-left: 0px;
-}
-
-dl.note
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #D0C000;
-}
-
-dl.warning, dl.attention
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #FF0000;
-}
-
-dl.pre, dl.post, dl.invariant
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #00D000;
-}
-
-dl.deprecated
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #505050;
-}
-
-dl.todo
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #00C0E0;
-}
-
-dl.test
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #3030E0;
-}
-
-dl.bug
-{
-        margin-left:-7px;
-        padding-left: 3px;
-        border-left:4px solid;
-        border-color: #C08050;
-}
-
-dl.section dd {
-	margin-bottom: 6px;
-}
-
-
-#projectlogo
-{
-	text-align: center;
-	vertical-align: bottom;
-	border-collapse: separate;
-}
- 
-#projectlogo img
-{ 
-	border: 0px none;
-}
- 
-#projectname
-{
-	font: 300% Tahoma, Arial,sans-serif;
-	margin: 0px;
-	padding: 2px 0px;
-}
-    
-#projectbrief
-{
-	font: 120% Tahoma, Arial,sans-serif;
-	margin: 0px;
-	padding: 0px;
-}
-
-#projectnumber
-{
-	font: 50% Tahoma, Arial,sans-serif;
-	margin: 0px;
-	padding: 0px;
-}
-
-#titlearea
-{
-	padding: 0px;
-	margin: 0px;
-	width: 100%;
-	border-bottom: 1px solid #5373B4;
-}
-
-.image
-{
-        text-align: center;
-}
-
-.dotgraph
-{
-        text-align: center;
-}
-
-.mscgraph
-{
-        text-align: center;
-}
-
-.caption
-{
-	font-weight: bold;
-}
-
-div.zoom
-{
-	border: 1px solid #90A5CE;
-}
-
-dl.citelist {
-        margin-bottom:50px;
-}
-
-dl.citelist dt {
-        color:#334975;
-        float:left;
-        font-weight:bold;
-        margin-right:10px;
-        padding:5px;
-}
-
-dl.citelist dd {
-        margin:2px 0;
-        padding:5px 0;
-}
-
-div.toc {
-        padding: 14px 25px;
-        background-color: #F4F6FA;
-        border: 1px solid #D8DFEE;
-        border-radius: 7px 7px 7px 7px;
-        float: right;
-        height: auto;
-        margin: 0 20px 10px 10px;
-        width: 200px;
-}
-
-div.toc li {
-        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
-        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
-        margin-top: 5px;
-        padding-left: 10px;
-        padding-top: 2px;
-}
-
-div.toc h3 {
-        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
-	color: #4665A2;
-        border-bottom: 0 none;
-        margin: 0;
-}
-
-div.toc ul {
-        list-style: none outside none;
-        border: medium none;
-        padding: 0px;
-}       
-
-div.toc li.level1 {
-        margin-left: 0px;
-}
-
-div.toc li.level2 {
-        margin-left: 15px;
-}
-
-div.toc li.level3 {
-        margin-left: 30px;
-}
-
-div.toc li.level4 {
-        margin-left: 45px;
-}
-
-.inherit_header {
-        font-weight: bold;
-        color: gray;
-        cursor: pointer;
-	-webkit-touch-callout: none;
-	-webkit-user-select: none;
-	-khtml-user-select: none;
-	-moz-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.inherit_header td {
-        padding: 6px 0px 2px 5px;
-}
-
-.inherit {
-        display: none;
-}
-
-tr.heading h2 {
-        margin-top: 12px;
-        margin-bottom: 4px;
-}
-
-@media print
-{
-  #top { display: none; }
-  #side-nav { display: none; }
-  #nav-path { display: none; }
-  body { overflow:visible; }
-  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
-  .summary { display: none; }
-  .memitem { page-break-inside: avoid; }
-  #doc-content
-  {
-    margin-left:0 !important;
-    height:auto !important;
-    width:auto !important;
-    overflow:inherit;
-    display:inline;
-  }
-}
-
diff --git a/src/third_party/libjpeg-turbo/doc/html/doxygen.png b/src/third_party/libjpeg-turbo/doc/html/doxygen.png
deleted file mode 100644
index 3ff17d8..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/doxygen.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/dynsections.js b/src/third_party/libjpeg-turbo/doc/html/dynsections.js
deleted file mode 100644
index ed092c7..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/dynsections.js
+++ /dev/null
@@ -1,97 +0,0 @@
-function toggleVisibility(linkObj)
-{
- var base = $(linkObj).attr('id');
- var summary = $('#'+base+'-summary');
- var content = $('#'+base+'-content');
- var trigger = $('#'+base+'-trigger');
- var src=$(trigger).attr('src');
- if (content.is(':visible')===true) {
-   content.hide();
-   summary.show();
-   $(linkObj).addClass('closed').removeClass('opened');
-   $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
- } else {
-   content.show();
-   summary.hide();
-   $(linkObj).removeClass('closed').addClass('opened');
-   $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
- } 
- return false;
-}
-
-function updateStripes()
-{
-  $('table.directory tr').
-       removeClass('even').filter(':visible:even').addClass('even');
-}
-function toggleLevel(level)
-{
-  $('table.directory tr').each(function(){ 
-    var l = this.id.split('_').length-1;
-    var i = $('#img'+this.id.substring(3));
-    var a = $('#arr'+this.id.substring(3));
-    if (l<level+1) {
-      i.attr('src','ftv2folderopen.png');
-      a.attr('src','ftv2mnode.png');
-      $(this).show();
-    } else if (l==level+1) {
-      i.attr('src','ftv2folderclosed.png');
-      a.attr('src','ftv2pnode.png');
-      $(this).show();
-    } else {
-      $(this).hide();
-    }
-  });
-  updateStripes();
-}
-
-function toggleFolder(id)
-{
-  //The clicked row
-  var currentRow = $('#row_'+id);
-  var currentRowImages = currentRow.find("img");
-
-  //All rows after the clicked row
-  var rows = currentRow.nextAll("tr");
-
-  //Only match elements AFTER this one (can't hide elements before)
-  var childRows = rows.filter(function() {
-    var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
-    return this.id.match(re);
-  });
-
-  //First row is visible we are HIDING
-  if (childRows.filter(':first').is(':visible')===true) {
-    currentRowImages.filter("[id^=arr]").attr('src', 'ftv2pnode.png');
-    currentRowImages.filter("[id^=img]").attr('src', 'ftv2folderclosed.png');
-    rows.filter("[id^=row_"+id+"]").hide();
-  } else { //We are SHOWING
-    //All sub images
-    var childImages = childRows.find("img");
-    var childImg = childImages.filter("[id^=img]");
-    var childArr = childImages.filter("[id^=arr]");
-
-    currentRow.find("[id^=arr]").attr('src', 'ftv2mnode.png'); //open row
-    currentRow.find("[id^=img]").attr('src', 'ftv2folderopen.png'); //open row
-    childImg.attr('src','ftv2folderclosed.png'); //children closed
-    childArr.attr('src','ftv2pnode.png'); //children closed
-    childRows.show(); //show all children
-  }
-  updateStripes();
-}
-
-
-function toggleInherit(id)
-{
-  var rows = $('tr.inherit.'+id);
-  var img = $('tr.inherit_header.'+id+' img');
-  var src = $(img).attr('src');
-  if (rows.filter(':first').is(':visible')===true) {
-    rows.css('display','none');
-    $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
-  } else {
-    rows.css('display','table-row'); // using show() causes jump in firefox
-    $(img).attr('src',src.substring(0,src.length-10)+'open.png');
-  }
-}
-
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2blank.png b/src/third_party/libjpeg-turbo/doc/html/ftv2blank.png
deleted file mode 100644
index 63c605b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2blank.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2cl.png b/src/third_party/libjpeg-turbo/doc/html/ftv2cl.png
deleted file mode 100644
index 132f657..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2cl.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2doc.png b/src/third_party/libjpeg-turbo/doc/html/ftv2doc.png
deleted file mode 100644
index 17edabf..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2doc.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2folderclosed.png b/src/third_party/libjpeg-turbo/doc/html/ftv2folderclosed.png
deleted file mode 100644
index bb8ab35..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2folderclosed.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2folderopen.png b/src/third_party/libjpeg-turbo/doc/html/ftv2folderopen.png
deleted file mode 100644
index d6c7f67..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2folderopen.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2lastnode.png b/src/third_party/libjpeg-turbo/doc/html/ftv2lastnode.png
deleted file mode 100644
index 63c605b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2lastnode.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2link.png b/src/third_party/libjpeg-turbo/doc/html/ftv2link.png
deleted file mode 100644
index 17edabf..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2link.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2mlastnode.png b/src/third_party/libjpeg-turbo/doc/html/ftv2mlastnode.png
deleted file mode 100644
index 0b63f6d..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2mlastnode.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2mnode.png b/src/third_party/libjpeg-turbo/doc/html/ftv2mnode.png
deleted file mode 100644
index 0b63f6d..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2mnode.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2mo.png b/src/third_party/libjpeg-turbo/doc/html/ftv2mo.png
deleted file mode 100644
index 4bfb80f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2mo.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2node.png b/src/third_party/libjpeg-turbo/doc/html/ftv2node.png
deleted file mode 100644
index 63c605b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2node.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2ns.png b/src/third_party/libjpeg-turbo/doc/html/ftv2ns.png
deleted file mode 100644
index 72e3d71..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2ns.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2plastnode.png b/src/third_party/libjpeg-turbo/doc/html/ftv2plastnode.png
deleted file mode 100644
index c6ee22f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2plastnode.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2pnode.png b/src/third_party/libjpeg-turbo/doc/html/ftv2pnode.png
deleted file mode 100644
index c6ee22f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2pnode.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2splitbar.png b/src/third_party/libjpeg-turbo/doc/html/ftv2splitbar.png
deleted file mode 100644
index fe895f2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2splitbar.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/ftv2vertline.png b/src/third_party/libjpeg-turbo/doc/html/ftv2vertline.png
deleted file mode 100644
index 63c605b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/ftv2vertline.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/functions.html b/src/third_party/libjpeg-turbo/doc/html/functions.html
deleted file mode 100644
index 1042ae7..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/functions.html
+++ /dev/null
@@ -1,134 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Data Fields</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li class="current"><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-  <div id="navrow3" class="tabs2">
-    <ul class="tablist">
-      <li class="current"><a href="functions.html"><span>All</span></a></li>
-      <li><a href="functions_vars.html"><span>Variables</span></a></li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="contents">
-<div class="textblock">Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:</div><ul>
-<li>customFilter
-: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
-</li>
-<li>data
-: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
-</li>
-<li>denom
-: <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
-</li>
-<li>h
-: <a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a>
-</li>
-<li>num
-: <a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a>
-</li>
-<li>op
-: <a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a>
-</li>
-<li>options
-: <a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a>
-</li>
-<li>r
-: <a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a>
-</li>
-<li>w
-: <a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a>
-</li>
-<li>x
-: <a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a>
-</li>
-<li>y
-: <a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a>
-</li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/functions_vars.html b/src/third_party/libjpeg-turbo/doc/html/functions_vars.html
deleted file mode 100644
index e0a7157..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/functions_vars.html
+++ /dev/null
@@ -1,134 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Data Fields - Variables</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li class="current"><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-  <div id="navrow3" class="tabs2">
-    <ul class="tablist">
-      <li><a href="functions.html"><span>All</span></a></li>
-      <li class="current"><a href="functions_vars.html"><span>Variables</span></a></li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="contents">
-&#160;<ul>
-<li>customFilter
-: <a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">tjtransform</a>
-</li>
-<li>data
-: <a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">tjtransform</a>
-</li>
-<li>denom
-: <a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">tjscalingfactor</a>
-</li>
-<li>h
-: <a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">tjregion</a>
-</li>
-<li>num
-: <a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">tjscalingfactor</a>
-</li>
-<li>op
-: <a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">tjtransform</a>
-</li>
-<li>options
-: <a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">tjtransform</a>
-</li>
-<li>r
-: <a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">tjtransform</a>
-</li>
-<li>w
-: <a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">tjregion</a>
-</li>
-<li>x
-: <a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">tjregion</a>
-</li>
-<li>y
-: <a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">tjregion</a>
-</li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/group___turbo_j_p_e_g.html b/src/third_party/libjpeg-turbo/doc/html/group___turbo_j_p_e_g.html
deleted file mode 100644
index cef856a..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/group___turbo_j_p_e_g.html
+++ /dev/null
@@ -1,2775 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: TurboJPEG</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="summary">
-<a href="#nested-classes">Data Structures</a> &#124;
-<a href="#define-members">Macros</a> &#124;
-<a href="#typedef-members">Typedefs</a> &#124;
-<a href="#enum-members">Enumerations</a> &#124;
-<a href="#func-members">Functions</a> &#124;
-<a href="#var-members">Variables</a>  </div>
-  <div class="headertitle">
-<div class="title">TurboJPEG</div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p>TurboJPEG API.  
-<a href="#details">More...</a></p>
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
-Data Structures</h2></td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjscalingfactor.html">tjscalingfactor</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Scaling factor.  <a href="structtjscalingfactor.html#details">More...</a><br/></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjregion.html">tjregion</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Cropping region.  <a href="structtjregion.html#details">More...</a><br/></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html">tjtransform</a></td></tr>
-<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lossless transform.  <a href="structtjtransform.html#details">More...</a><br/></td></tr>
-<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="define-members"></a>
-Macros</h2></td></tr>
-<tr class="memitem:ga5ef3d169162ce77ce348e292a0b7477c"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c">TJ_NUMSAMP</a></td></tr>
-<tr class="memdesc:ga5ef3d169162ce77ce348e292a0b7477c"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of chrominance subsampling options.  <a href="#ga5ef3d169162ce77ce348e292a0b7477c">More...</a><br/></td></tr>
-<tr class="separator:ga5ef3d169162ce77ce348e292a0b7477c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga7010a4402f54a45ba822ad8675a4655e"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a></td></tr>
-<tr class="memdesc:ga7010a4402f54a45ba822ad8675a4655e"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of pixel formats.  <a href="#ga7010a4402f54a45ba822ad8675a4655e">More...</a><br/></td></tr>
-<tr class="separator:ga7010a4402f54a45ba822ad8675a4655e"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga39f57a6fb02d9cf32e7b6890099b5a71"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71">TJ_NUMCS</a></td></tr>
-<tr class="memdesc:ga39f57a6fb02d9cf32e7b6890099b5a71"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of JPEG colorspaces.  <a href="#ga39f57a6fb02d9cf32e7b6890099b5a71">More...</a><br/></td></tr>
-<tr class="separator:ga39f57a6fb02d9cf32e7b6890099b5a71"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga72ecf4ebe6eb702d3c6f5ca27455e1ec"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">TJFLAG_BOTTOMUP</a></td></tr>
-<tr class="memdesc:ga72ecf4ebe6eb702d3c6f5ca27455e1ec"><td class="mdescLeft">&#160;</td><td class="mdescRight">The uncompressed source/destination image is stored in bottom-up (Windows, OpenGL) order, not top-down (X11) order.  <a href="#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">More...</a><br/></td></tr>
-<tr class="separator:ga72ecf4ebe6eb702d3c6f5ca27455e1ec"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga4ee4506c81177a06f77e2504a22efd2d"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga4ee4506c81177a06f77e2504a22efd2d">TJFLAG_FASTUPSAMPLE</a></td></tr>
-<tr class="memdesc:ga4ee4506c81177a06f77e2504a22efd2d"><td class="mdescLeft">&#160;</td><td class="mdescRight">When decompressing an image that was compressed using chrominance subsampling, use the fastest chrominance upsampling algorithm available in the underlying codec.  <a href="#ga4ee4506c81177a06f77e2504a22efd2d">More...</a><br/></td></tr>
-<tr class="separator:ga4ee4506c81177a06f77e2504a22efd2d"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga8808d403c68b62aaa58a4c1e58e98963"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963">TJFLAG_NOREALLOC</a></td></tr>
-<tr class="memdesc:ga8808d403c68b62aaa58a4c1e58e98963"><td class="mdescLeft">&#160;</td><td class="mdescRight">Disable buffer (re)allocation.  <a href="#ga8808d403c68b62aaa58a4c1e58e98963">More...</a><br/></td></tr>
-<tr class="separator:ga8808d403c68b62aaa58a4c1e58e98963"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaabce235db80d3f698b27f36cbd453da2"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaabce235db80d3f698b27f36cbd453da2">TJFLAG_FASTDCT</a></td></tr>
-<tr class="memdesc:gaabce235db80d3f698b27f36cbd453da2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Use the fastest DCT/IDCT algorithm available in the underlying codec.  <a href="#gaabce235db80d3f698b27f36cbd453da2">More...</a><br/></td></tr>
-<tr class="separator:gaabce235db80d3f698b27f36cbd453da2"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gacb233cfd722d66d1ccbf48a7de81f0e0"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">TJFLAG_ACCURATEDCT</a></td></tr>
-<tr class="memdesc:gacb233cfd722d66d1ccbf48a7de81f0e0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Use the most accurate DCT/IDCT algorithm available in the underlying codec.  <a href="#gacb233cfd722d66d1ccbf48a7de81f0e0">More...</a><br/></td></tr>
-<tr class="separator:gacb233cfd722d66d1ccbf48a7de81f0e0"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga519cfa4ef6c18d9e5b455fdf59306a3a"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga519cfa4ef6c18d9e5b455fdf59306a3a">TJFLAG_STOPONWARNING</a></td></tr>
-<tr class="memdesc:ga519cfa4ef6c18d9e5b455fdf59306a3a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Immediately discontinue the current compression/decompression/transform operation if the underlying codec throws a warning (non-fatal error).  <a href="#ga519cfa4ef6c18d9e5b455fdf59306a3a">More...</a><br/></td></tr>
-<tr class="separator:ga519cfa4ef6c18d9e5b455fdf59306a3a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga43b426750b46190a25d34a67ef76df1b"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga43b426750b46190a25d34a67ef76df1b">TJFLAG_PROGRESSIVE</a></td></tr>
-<tr class="memdesc:ga43b426750b46190a25d34a67ef76df1b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Use progressive entropy coding in JPEG images generated by the compression and transform functions.  <a href="#ga43b426750b46190a25d34a67ef76df1b">More...</a><br/></td></tr>
-<tr class="separator:ga43b426750b46190a25d34a67ef76df1b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga79bde1b4a3e2351e00887e47781b966e"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga79bde1b4a3e2351e00887e47781b966e">TJ_NUMERR</a></td></tr>
-<tr class="memdesc:ga79bde1b4a3e2351e00887e47781b966e"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of error codes.  <a href="#ga79bde1b4a3e2351e00887e47781b966e">More...</a><br/></td></tr>
-<tr class="separator:ga79bde1b4a3e2351e00887e47781b966e"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga0f6dbd18adf38b7d46ac547f0f4d562c"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c">TJ_NUMXOP</a></td></tr>
-<tr class="memdesc:ga0f6dbd18adf38b7d46ac547f0f4d562c"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of transform operations.  <a href="#ga0f6dbd18adf38b7d46ac547f0f4d562c">More...</a><br/></td></tr>
-<tr class="separator:ga0f6dbd18adf38b7d46ac547f0f4d562c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga50e03cb5ed115330e212417429600b00"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00">TJXOPT_PERFECT</a></td></tr>
-<tr class="memdesc:ga50e03cb5ed115330e212417429600b00"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will cause <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> to return an error if the transform is not perfect.  <a href="#ga50e03cb5ed115330e212417429600b00">More...</a><br/></td></tr>
-<tr class="separator:ga50e03cb5ed115330e212417429600b00"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga319826b7eb1583c0595bbe7b95428709"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga319826b7eb1583c0595bbe7b95428709">TJXOPT_TRIM</a></td></tr>
-<tr class="memdesc:ga319826b7eb1583c0595bbe7b95428709"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will cause <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> to discard any partial MCU blocks that cannot be transformed.  <a href="#ga319826b7eb1583c0595bbe7b95428709">More...</a><br/></td></tr>
-<tr class="separator:ga319826b7eb1583c0595bbe7b95428709"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga9c771a757fc1294add611906b89ab2d2"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2">TJXOPT_CROP</a></td></tr>
-<tr class="memdesc:ga9c771a757fc1294add611906b89ab2d2"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will enable lossless cropping.  <a href="#ga9c771a757fc1294add611906b89ab2d2">More...</a><br/></td></tr>
-<tr class="separator:ga9c771a757fc1294add611906b89ab2d2"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga3acee7b48ade1b99e5588736007c2589"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga3acee7b48ade1b99e5588736007c2589">TJXOPT_GRAY</a></td></tr>
-<tr class="memdesc:ga3acee7b48ade1b99e5588736007c2589"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will discard the color data in the input image and produce a grayscale output image.  <a href="#ga3acee7b48ade1b99e5588736007c2589">More...</a><br/></td></tr>
-<tr class="separator:ga3acee7b48ade1b99e5588736007c2589"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gafbf992bbf6e006705886333703ffab31"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gafbf992bbf6e006705886333703ffab31">TJXOPT_NOOUTPUT</a></td></tr>
-<tr class="memdesc:gafbf992bbf6e006705886333703ffab31"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will prevent <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> from outputting a JPEG image for this particular transform (this can be used in conjunction with a custom filter to capture the transformed DCT coefficients without transcoding them.)  <a href="#gafbf992bbf6e006705886333703ffab31">More...</a><br/></td></tr>
-<tr class="separator:gafbf992bbf6e006705886333703ffab31"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gad2371c80674584ecc1a7d75e564cf026"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gad2371c80674584ecc1a7d75e564cf026">TJXOPT_PROGRESSIVE</a></td></tr>
-<tr class="memdesc:gad2371c80674584ecc1a7d75e564cf026"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will enable progressive entropy coding in the output image generated by this particular transform.  <a href="#gad2371c80674584ecc1a7d75e564cf026">More...</a><br/></td></tr>
-<tr class="separator:gad2371c80674584ecc1a7d75e564cf026"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga153b468cfb905d0de61706c838986fe8"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8">TJXOPT_COPYNONE</a></td></tr>
-<tr class="memdesc:ga153b468cfb905d0de61706c838986fe8"><td class="mdescLeft">&#160;</td><td class="mdescRight">This option will prevent <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> from copying any extra markers (including EXIF and ICC profile data) from the source image to the output image.  <a href="#ga153b468cfb905d0de61706c838986fe8">More...</a><br/></td></tr>
-<tr class="separator:ga153b468cfb905d0de61706c838986fe8"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga0aba955473315e405295d978f0c16511"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511">TJPAD</a>(width)</td></tr>
-<tr class="memdesc:ga0aba955473315e405295d978f0c16511"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pad the given width to the nearest 32-bit boundary.  <a href="#ga0aba955473315e405295d978f0c16511">More...</a><br/></td></tr>
-<tr class="separator:ga0aba955473315e405295d978f0c16511"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga84878bb65404204743aa18cac02781df"><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df">TJSCALED</a>(dimension, scalingFactor)</td></tr>
-<tr class="memdesc:ga84878bb65404204743aa18cac02781df"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compute the scaled value of <code>dimension</code> using the given scaling factor.  <a href="#ga84878bb65404204743aa18cac02781df">More...</a><br/></td></tr>
-<tr class="separator:ga84878bb65404204743aa18cac02781df"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="typedef-members"></a>
-Typedefs</h2></td></tr>
-<tr class="memitem:gaa29f3189c41be12ec5dee7caec318a31"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structtjtransform.html">tjtransform</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31">tjtransform</a></td></tr>
-<tr class="memdesc:gaa29f3189c41be12ec5dee7caec318a31"><td class="mdescLeft">&#160;</td><td class="mdescRight">Lossless transform.  <a href="#gaa29f3189c41be12ec5dee7caec318a31">More...</a><br/></td></tr>
-<tr class="separator:gaa29f3189c41be12ec5dee7caec318a31"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga758d2634ecb4949de7815cba621f5763"><td class="memItemLeft" align="right" valign="top">typedef void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a></td></tr>
-<tr class="memdesc:ga758d2634ecb4949de7815cba621f5763"><td class="mdescLeft">&#160;</td><td class="mdescRight">TurboJPEG instance handle.  <a href="#ga758d2634ecb4949de7815cba621f5763">More...</a><br/></td></tr>
-<tr class="separator:ga758d2634ecb4949de7815cba621f5763"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="enum-members"></a>
-Enumerations</h2></td></tr>
-<tr class="memitem:ga1d047060ea80bb9820d540bb928e9074"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">TJSAMP</a> { <br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3">TJSAMP_444</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404">TJSAMP_422</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737">TJSAMP_420</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248">TJSAMP_GRAY</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974">TJSAMP_440</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2">TJSAMP_411</a>
-<br/>
- }</td></tr>
-<tr class="memdesc:ga1d047060ea80bb9820d540bb928e9074"><td class="mdescLeft">&#160;</td><td class="mdescRight">Chrominance subsampling options.  <a href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">More...</a><br/></td></tr>
-<tr class="separator:ga1d047060ea80bb9820d540bb928e9074"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gac916144e26c3817ac514e64ae5d12e2a"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">TJPF</a> { <br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c">TJPF_RGB</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839">TJPF_BGR</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01">TJPF_RGBX</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8">TJPF_BGRX</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af">TJPF_XBGR</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84">TJPF_XRGB</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12">TJPF_RGBA</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4">TJPF_BGRA</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081">TJPF_ABGR</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c">TJPF_ARGB</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed">TJPF_UNKNOWN</a>
-<br/>
- }</td></tr>
-<tr class="memdesc:gac916144e26c3817ac514e64ae5d12e2a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pixel formats.  <a href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">More...</a><br/></td></tr>
-<tr class="separator:gac916144e26c3817ac514e64ae5d12e2a"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga4f83ad3368e0e29d1957be0efa7c3720"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720">TJCS</a> { <br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555">TJCS_RGB</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75">TJCS_YCbCr</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a">TJCS_GRAY</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53">TJCS_CMYK</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e">TJCS_YCCK</a>
-<br/>
- }</td></tr>
-<tr class="memdesc:ga4f83ad3368e0e29d1957be0efa7c3720"><td class="mdescLeft">&#160;</td><td class="mdescRight">JPEG colorspaces.  <a href="group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720">More...</a><br/></td></tr>
-<tr class="separator:ga4f83ad3368e0e29d1957be0efa7c3720"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gafbc17cfa57d0d5d11fea35ac025950fe"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe">TJERR</a> { <a class="el" href="group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59">TJERR_WARNING</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a">TJERR_FATAL</a>
- }</td></tr>
-<tr class="memdesc:gafbc17cfa57d0d5d11fea35ac025950fe"><td class="mdescLeft">&#160;</td><td class="mdescRight">Error codes.  <a href="group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe">More...</a><br/></td></tr>
-<tr class="separator:gafbc17cfa57d0d5d11fea35ac025950fe"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga2de531af4e7e6c4f124908376b354866"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">TJXOP</a> { <br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27">TJXOP_NONE</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce">TJXOP_HFLIP</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d">TJXOP_VFLIP</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d">TJXOP_TRANSPOSE</a>, 
-<br/>
-&#160;&#160;<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4">TJXOP_TRANSVERSE</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128">TJXOP_ROT90</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692">TJXOP_ROT180</a>, 
-<a class="el" href="group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08">TJXOP_ROT270</a>
-<br/>
- }</td></tr>
-<tr class="memdesc:ga2de531af4e7e6c4f124908376b354866"><td class="mdescLeft">&#160;</td><td class="mdescRight">Transform operations for <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a>  <a href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">More...</a><br/></td></tr>
-<tr class="separator:ga2de531af4e7e6c4f124908376b354866"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
-Functions</h2></td></tr>
-<tr class="memitem:ga9d63a05fc6d813f4aae06107041a37e8"><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9d63a05fc6d813f4aae06107041a37e8">tjInitCompress</a> (void)</td></tr>
-<tr class="memdesc:ga9d63a05fc6d813f4aae06107041a37e8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Create a TurboJPEG compressor instance.  <a href="#ga9d63a05fc6d813f4aae06107041a37e8">More...</a><br/></td></tr>
-<tr class="separator:ga9d63a05fc6d813f4aae06107041a37e8"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gafbdce0112fd78fd38efae841443a9bcf"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gafbdce0112fd78fd38efae841443a9bcf">tjCompress2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)</td></tr>
-<tr class="memdesc:gafbdce0112fd78fd38efae841443a9bcf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compress an RGB, grayscale, or CMYK image into a JPEG image.  <a href="#gafbdce0112fd78fd38efae841443a9bcf">More...</a><br/></td></tr>
-<tr class="separator:gafbdce0112fd78fd38efae841443a9bcf"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga7622a459b79aa1007e005b58783f875b"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga7622a459b79aa1007e005b58783f875b">tjCompressFromYUV</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *srcBuf, int width, int pad, int height, int subsamp, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flags)</td></tr>
-<tr class="memdesc:ga7622a459b79aa1007e005b58783f875b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compress a YUV planar image into a JPEG image.  <a href="#ga7622a459b79aa1007e005b58783f875b">More...</a><br/></td></tr>
-<tr class="separator:ga7622a459b79aa1007e005b58783f875b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga29ec5dfbd2d84b8724e951d6fa0d5d9e"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga29ec5dfbd2d84b8724e951d6fa0d5d9e">tjCompressFromYUVPlanes</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char **srcPlanes, int width, const int *strides, int height, int subsamp, unsigned char **jpegBuf, unsigned long *jpegSize, int jpegQual, int flags)</td></tr>
-<tr class="memdesc:ga29ec5dfbd2d84b8724e951d6fa0d5d9e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Compress a set of Y, U (Cb), and V (Cr) image planes into a JPEG image.  <a href="#ga29ec5dfbd2d84b8724e951d6fa0d5d9e">More...</a><br/></td></tr>
-<tr class="separator:ga29ec5dfbd2d84b8724e951d6fa0d5d9e"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga67ac12fee79073242cb216e07c9f1f90"><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90">tjBufSize</a> (int width, int height, int jpegSubsamp)</td></tr>
-<tr class="memdesc:ga67ac12fee79073242cb216e07c9f1f90"><td class="mdescLeft">&#160;</td><td class="mdescRight">The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.  <a href="#ga67ac12fee79073242cb216e07c9f1f90">More...</a><br/></td></tr>
-<tr class="separator:ga67ac12fee79073242cb216e07c9f1f90"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga2be2b9969d4df9ecce9b05deed273194"><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194">tjBufSizeYUV2</a> (int width, int pad, int height, int subsamp)</td></tr>
-<tr class="memdesc:ga2be2b9969d4df9ecce9b05deed273194"><td class="mdescLeft">&#160;</td><td class="mdescRight">The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters.  <a href="#ga2be2b9969d4df9ecce9b05deed273194">More...</a><br/></td></tr>
-<tr class="separator:ga2be2b9969d4df9ecce9b05deed273194"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gab4ab7b24f6e797d79abaaa670373961d"><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned long&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d">tjPlaneSizeYUV</a> (int componentID, int width, int stride, int height, int subsamp)</td></tr>
-<tr class="memdesc:gab4ab7b24f6e797d79abaaa670373961d"><td class="mdescLeft">&#160;</td><td class="mdescRight">The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters.  <a href="#gab4ab7b24f6e797d79abaaa670373961d">More...</a><br/></td></tr>
-<tr class="separator:gab4ab7b24f6e797d79abaaa670373961d"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga63fb66bb1e36c74008c4634360becbb1"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga63fb66bb1e36c74008c4634360becbb1">tjPlaneWidth</a> (int componentID, int width, int subsamp)</td></tr>
-<tr class="memdesc:ga63fb66bb1e36c74008c4634360becbb1"><td class="mdescLeft">&#160;</td><td class="mdescRight">The plane width of a YUV image plane with the given parameters.  <a href="#ga63fb66bb1e36c74008c4634360becbb1">More...</a><br/></td></tr>
-<tr class="separator:ga63fb66bb1e36c74008c4634360becbb1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga1a209696c6a80748f20e134b3c64789f"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga1a209696c6a80748f20e134b3c64789f">tjPlaneHeight</a> (int componentID, int height, int subsamp)</td></tr>
-<tr class="memdesc:ga1a209696c6a80748f20e134b3c64789f"><td class="mdescLeft">&#160;</td><td class="mdescRight">The plane height of a YUV image plane with the given parameters.  <a href="#ga1a209696c6a80748f20e134b3c64789f">More...</a><br/></td></tr>
-<tr class="separator:ga1a209696c6a80748f20e134b3c64789f"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gac519b922cdf446e97d0cdcba513636bf"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gac519b922cdf446e97d0cdcba513636bf">tjEncodeYUV3</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int pad, int subsamp, int flags)</td></tr>
-<tr class="memdesc:gac519b922cdf446e97d0cdcba513636bf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Encode an RGB or grayscale image into a YUV planar image.  <a href="#gac519b922cdf446e97d0cdcba513636bf">More...</a><br/></td></tr>
-<tr class="separator:gac519b922cdf446e97d0cdcba513636bf"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae2d04c72457fe7f4d60cf78ab1b1feb1"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gae2d04c72457fe7f4d60cf78ab1b1feb1">tjEncodeYUVPlanes</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **dstPlanes, int *strides, int subsamp, int flags)</td></tr>
-<tr class="memdesc:gae2d04c72457fe7f4d60cf78ab1b1feb1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Encode an RGB or grayscale image into separate Y, U (Cb), and V (Cr) image planes.  <a href="#gae2d04c72457fe7f4d60cf78ab1b1feb1">More...</a><br/></td></tr>
-<tr class="separator:gae2d04c72457fe7f4d60cf78ab1b1feb1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga52300eac3f3d9ef4bab303bc244f62d3"><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga52300eac3f3d9ef4bab303bc244f62d3">tjInitDecompress</a> (void)</td></tr>
-<tr class="memdesc:ga52300eac3f3d9ef4bab303bc244f62d3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Create a TurboJPEG decompressor instance.  <a href="#ga52300eac3f3d9ef4bab303bc244f62d3">More...</a><br/></td></tr>
-<tr class="separator:ga52300eac3f3d9ef4bab303bc244f62d3"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga0595681096bba7199cc6f3533cb25f77"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga0595681096bba7199cc6f3533cb25f77">tjDecompressHeader3</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp, int *jpegColorspace)</td></tr>
-<tr class="memdesc:ga0595681096bba7199cc6f3533cb25f77"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieve information about a JPEG image without decompressing it.  <a href="#ga0595681096bba7199cc6f3533cb25f77">More...</a><br/></td></tr>
-<tr class="separator:ga0595681096bba7199cc6f3533cb25f77"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gac3854476006b10787bd128f7ede48057"><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="structtjscalingfactor.html">tjscalingfactor</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gac3854476006b10787bd128f7ede48057">tjGetScalingFactors</a> (int *numscalingfactors)</td></tr>
-<tr class="memdesc:gac3854476006b10787bd128f7ede48057"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of TurboJPEG supports.  <a href="#gac3854476006b10787bd128f7ede48057">More...</a><br/></td></tr>
-<tr class="separator:gac3854476006b10787bd128f7ede48057"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gae9eccef8b682a48f43a9117c231ed013"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gae9eccef8b682a48f43a9117c231ed013">tjDecompress2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, int flags)</td></tr>
-<tr class="memdesc:gae9eccef8b682a48f43a9117c231ed013"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image to an RGB, grayscale, or CMYK image.  <a href="#gae9eccef8b682a48f43a9117c231ed013">More...</a><br/></td></tr>
-<tr class="separator:gae9eccef8b682a48f43a9117c231ed013"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga04d1e839ff9a0860dd1475cff78d3364"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga04d1e839ff9a0860dd1475cff78d3364">tjDecompressToYUV2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, int width, int pad, int height, int flags)</td></tr>
-<tr class="memdesc:ga04d1e839ff9a0860dd1475cff78d3364"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image to a YUV planar image.  <a href="#ga04d1e839ff9a0860dd1475cff78d3364">More...</a><br/></td></tr>
-<tr class="separator:ga04d1e839ff9a0860dd1475cff78d3364"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaa59f901a5258ada5bd0185ad59368540"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaa59f901a5258ada5bd0185ad59368540">tjDecompressToYUVPlanes</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *jpegBuf, unsigned long jpegSize, unsigned char **dstPlanes, int width, int *strides, int height, int flags)</td></tr>
-<tr class="memdesc:gaa59f901a5258ada5bd0185ad59368540"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decompress a JPEG image into separate Y, U (Cb), and V (Cr) image planes.  <a href="#gaa59f901a5258ada5bd0185ad59368540">More...</a><br/></td></tr>
-<tr class="separator:gaa59f901a5258ada5bd0185ad59368540"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga70abbf38f77a26fd6da8813bef96f695"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga70abbf38f77a26fd6da8813bef96f695">tjDecodeYUV</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *srcBuf, int pad, int subsamp, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, int flags)</td></tr>
-<tr class="memdesc:ga70abbf38f77a26fd6da8813bef96f695"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decode a YUV planar image into an RGB or grayscale image.  <a href="#ga70abbf38f77a26fd6da8813bef96f695">More...</a><br/></td></tr>
-<tr class="separator:ga70abbf38f77a26fd6da8813bef96f695"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga10e837c07fa9d25770565b237d3898d9"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga10e837c07fa9d25770565b237d3898d9">tjDecodeYUVPlanes</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char **srcPlanes, const int *strides, int subsamp, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat, int flags)</td></tr>
-<tr class="memdesc:ga10e837c07fa9d25770565b237d3898d9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decode a set of Y, U (Cb), and V (Cr) image planes into an RGB or grayscale image.  <a href="#ga10e837c07fa9d25770565b237d3898d9">More...</a><br/></td></tr>
-<tr class="separator:ga10e837c07fa9d25770565b237d3898d9"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga928beff6ac248ceadf01089fc6b41957"><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga928beff6ac248ceadf01089fc6b41957">tjInitTransform</a> (void)</td></tr>
-<tr class="memdesc:ga928beff6ac248ceadf01089fc6b41957"><td class="mdescLeft">&#160;</td><td class="mdescRight">Create a new TurboJPEG transformer instance.  <a href="#ga928beff6ac248ceadf01089fc6b41957">More...</a><br/></td></tr>
-<tr class="separator:ga928beff6ac248ceadf01089fc6b41957"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga9cb8abf4cc91881e04a0329b2270be25"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25">tjTransform</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, unsigned char **dstBufs, unsigned long *dstSizes, <a class="el" href="structtjtransform.html">tjtransform</a> *transforms, int flags)</td></tr>
-<tr class="memdesc:ga9cb8abf4cc91881e04a0329b2270be25"><td class="mdescLeft">&#160;</td><td class="mdescRight">Losslessly transform a JPEG image into another JPEG image.  <a href="#ga9cb8abf4cc91881e04a0329b2270be25">More...</a><br/></td></tr>
-<tr class="separator:ga9cb8abf4cc91881e04a0329b2270be25"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga75f355fa27225ba1a4ee392c852394d2"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga75f355fa27225ba1a4ee392c852394d2">tjDestroy</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle)</td></tr>
-<tr class="memdesc:ga75f355fa27225ba1a4ee392c852394d2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroy a TurboJPEG compressor, decompressor, or transformer instance.  <a href="#ga75f355fa27225ba1a4ee392c852394d2">More...</a><br/></td></tr>
-<tr class="separator:ga75f355fa27225ba1a4ee392c852394d2"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaec627dd4c5f30b7a775a7aea3bec5d83"><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83">tjAlloc</a> (int bytes)</td></tr>
-<tr class="memdesc:gaec627dd4c5f30b7a775a7aea3bec5d83"><td class="mdescLeft">&#160;</td><td class="mdescRight">Allocate an image buffer for use with TurboJPEG.  <a href="#gaec627dd4c5f30b7a775a7aea3bec5d83">More...</a><br/></td></tr>
-<tr class="separator:gaec627dd4c5f30b7a775a7aea3bec5d83"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaffbd83c375e79f5db4b5c5d8ad4466e7"><td class="memItemLeft" align="right" valign="top">DLLEXPORT unsigned char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaffbd83c375e79f5db4b5c5d8ad4466e7">tjLoadImage</a> (const char *filename, int *width, int align, int *height, int *pixelFormat, int flags)</td></tr>
-<tr class="memdesc:gaffbd83c375e79f5db4b5c5d8ad4466e7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Load an uncompressed image from disk into memory.  <a href="#gaffbd83c375e79f5db4b5c5d8ad4466e7">More...</a><br/></td></tr>
-<tr class="separator:gaffbd83c375e79f5db4b5c5d8ad4466e7"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga6f445b22d8933ae4815b3370a538d879"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga6f445b22d8933ae4815b3370a538d879">tjSaveImage</a> (const char *filename, unsigned char *buffer, int width, int pitch, int height, int pixelFormat, int flags)</td></tr>
-<tr class="memdesc:ga6f445b22d8933ae4815b3370a538d879"><td class="mdescLeft">&#160;</td><td class="mdescRight">Save an uncompressed image from memory to disk.  <a href="#ga6f445b22d8933ae4815b3370a538d879">More...</a><br/></td></tr>
-<tr class="separator:ga6f445b22d8933ae4815b3370a538d879"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gaea863d2da0cdb609563aabdf9196514b"><td class="memItemLeft" align="right" valign="top">DLLEXPORT void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaea863d2da0cdb609563aabdf9196514b">tjFree</a> (unsigned char *buffer)</td></tr>
-<tr class="memdesc:gaea863d2da0cdb609563aabdf9196514b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Free an image buffer previously allocated by TurboJPEG.  <a href="#gaea863d2da0cdb609563aabdf9196514b">More...</a><br/></td></tr>
-<tr class="separator:gaea863d2da0cdb609563aabdf9196514b"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga1ead8574f9f39fbafc6b497124e7aafa"><td class="memItemLeft" align="right" valign="top">DLLEXPORT char *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa">tjGetErrorStr2</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle)</td></tr>
-<tr class="memdesc:ga1ead8574f9f39fbafc6b497124e7aafa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a descriptive error message explaining why the last command failed.  <a href="#ga1ead8574f9f39fbafc6b497124e7aafa">More...</a><br/></td></tr>
-<tr class="separator:ga1ead8574f9f39fbafc6b497124e7aafa"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga414feeffbf860ebd31c745df203de410"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410">tjGetErrorCode</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle)</td></tr>
-<tr class="memdesc:ga414feeffbf860ebd31c745df203de410"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a code indicating the severity of the last error.  <a href="#ga414feeffbf860ebd31c745df203de410">More...</a><br/></td></tr>
-<tr class="separator:ga414feeffbf860ebd31c745df203de410"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table><table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="var-members"></a>
-Variables</h2></td></tr>
-<tr class="memitem:ga9e61e7cd47a15a173283ba94e781308c"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c">tjMCUWidth</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c">TJ_NUMSAMP</a>]</td></tr>
-<tr class="memdesc:ga9e61e7cd47a15a173283ba94e781308c"><td class="mdescLeft">&#160;</td><td class="mdescRight">MCU block width (in pixels) for a given level of chrominance subsampling.  <a href="#ga9e61e7cd47a15a173283ba94e781308c">More...</a><br/></td></tr>
-<tr class="separator:ga9e61e7cd47a15a173283ba94e781308c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gabd247bb9fecb393eca57366feb8327bf"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf">tjMCUHeight</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c">TJ_NUMSAMP</a>]</td></tr>
-<tr class="memdesc:gabd247bb9fecb393eca57366feb8327bf"><td class="mdescLeft">&#160;</td><td class="mdescRight">MCU block height (in pixels) for a given level of chrominance subsampling.  <a href="#gabd247bb9fecb393eca57366feb8327bf">More...</a><br/></td></tr>
-<tr class="separator:gabd247bb9fecb393eca57366feb8327bf"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gadd9b446742ac8a3923f7992c7988fea8"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8">tjRedOffset</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td></tr>
-<tr class="memdesc:gadd9b446742ac8a3923f7992c7988fea8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Red offset (in bytes) for a given pixel format.  <a href="#gadd9b446742ac8a3923f7992c7988fea8">More...</a><br/></td></tr>
-<tr class="separator:gadd9b446742ac8a3923f7992c7988fea8"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga82d6e35da441112a411da41923c0ba2f"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f">tjGreenOffset</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td></tr>
-<tr class="memdesc:ga82d6e35da441112a411da41923c0ba2f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Green offset (in bytes) for a given pixel format.  <a href="#ga82d6e35da441112a411da41923c0ba2f">More...</a><br/></td></tr>
-<tr class="separator:ga82d6e35da441112a411da41923c0ba2f"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga84e2e35d3f08025f976ec1ec53693dea"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea">tjBlueOffset</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td></tr>
-<tr class="memdesc:ga84e2e35d3f08025f976ec1ec53693dea"><td class="mdescLeft">&#160;</td><td class="mdescRight">Blue offset (in bytes) for a given pixel format.  <a href="#ga84e2e35d3f08025f976ec1ec53693dea">More...</a><br/></td></tr>
-<tr class="separator:ga84e2e35d3f08025f976ec1ec53693dea"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ga5af0ab065feefd526debf1e20c43e837"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837">tjAlphaOffset</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td></tr>
-<tr class="memdesc:ga5af0ab065feefd526debf1e20c43e837"><td class="mdescLeft">&#160;</td><td class="mdescRight">Alpha offset (in bytes) for a given pixel format.  <a href="#ga5af0ab065feefd526debf1e20c43e837">More...</a><br/></td></tr>
-<tr class="separator:ga5af0ab065feefd526debf1e20c43e837"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:gad77cf8fe5b2bfd3cb3f53098146abb4c"><td class="memItemLeft" align="right" valign="top">static const int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c">tjPixelSize</a> [<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td></tr>
-<tr class="memdesc:gad77cf8fe5b2bfd3cb3f53098146abb4c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Pixel size (in bytes) for a given pixel format.  <a href="#gad77cf8fe5b2bfd3cb3f53098146abb4c">More...</a><br/></td></tr>
-<tr class="separator:gad77cf8fe5b2bfd3cb3f53098146abb4c"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<p>TurboJPEG API. </p>
-<p>This API provides an interface for generating, decoding, and transforming planar YUV and JPEG images in memory.</p>
-<p><a class="anchor" id="YUVnotes"></a></p>
-<h2>YUV Image Format Notes</h2>
-<p>Technically, the JPEG format uses the YCbCr colorspace (which is technically not a colorspace but a color transform), but per the convention of the digital video community, the TurboJPEG API uses "YUV" to refer to an image format consisting of Y, Cb, and Cr image planes.</p>
-<p>Each plane is simply a 2D array of bytes, each byte representing the value of one of the components (Y, Cb, or Cr) at a particular location in the image. The width and height of each plane are determined by the image width, height, and level of chrominance subsampling. The luminance plane width is the image width padded to the nearest multiple of the horizontal subsampling factor (2 in the case of 4:2:0 and 4:2:2, 4 in the case of 4:1:1, 1 in the case of 4:4:4 or grayscale.) Similarly, the luminance plane height is the image height padded to the nearest multiple of the vertical subsampling factor (2 in the case of 4:2:0 or 4:4:0, 1 in the case of 4:4:4 or grayscale.) This is irrespective of any additional padding that may be specified as an argument to the various YUV functions. The chrominance plane width is equal to the luminance plane width divided by the horizontal subsampling factor, and the chrominance plane height is equal to the luminance plane height divided by the vertical subsampling factor.</p>
-<p>For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is used, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 18 x 35 bytes. If you specify a line padding of 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 20 x 35 bytes. </p>
-<h2 class="groupheader">Macro Definition Documentation</h2>
-<a class="anchor" id="ga39f57a6fb02d9cf32e7b6890099b5a71"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJ_NUMCS</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The number of JPEG colorspaces. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga79bde1b4a3e2351e00887e47781b966e"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJ_NUMERR</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The number of error codes. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga7010a4402f54a45ba822ad8675a4655e"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJ_NUMPF</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The number of pixel formats. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga5ef3d169162ce77ce348e292a0b7477c"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJ_NUMSAMP</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The number of chrominance subsampling options. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga0f6dbd18adf38b7d46ac547f0f4d562c"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJ_NUMXOP</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The number of transform operations. </p>
-
-</div>
-</div>
-<a class="anchor" id="gacb233cfd722d66d1ccbf48a7de81f0e0"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_ACCURATEDCT</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Use the most accurate DCT/IDCT algorithm available in the underlying codec. </p>
-<p>The default if this flag is not specified is implementation-specific. For example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast algorithm by default when compressing, because this has been shown to have only a very slight effect on accuracy, but it uses the accurate algorithm when decompressing, because this has been shown to have a larger effect. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga72ecf4ebe6eb702d3c6f5ca27455e1ec"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_BOTTOMUP</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The uncompressed source/destination image is stored in bottom-up (Windows, OpenGL) order, not top-down (X11) order. </p>
-
-</div>
-</div>
-<a class="anchor" id="gaabce235db80d3f698b27f36cbd453da2"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_FASTDCT</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Use the fastest DCT/IDCT algorithm available in the underlying codec. </p>
-<p>The default if this flag is not specified is implementation-specific. For example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast algorithm by default when compressing, because this has been shown to have only a very slight effect on accuracy, but it uses the accurate algorithm when decompressing, because this has been shown to have a larger effect. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga4ee4506c81177a06f77e2504a22efd2d"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_FASTUPSAMPLE</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>When decompressing an image that was compressed using chrominance subsampling, use the fastest chrominance upsampling algorithm available in the underlying codec. </p>
-<p>The default is to use smooth upsampling, which creates a smooth transition between neighboring chrominance components in order to reduce upsampling artifacts in the decompressed image. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga8808d403c68b62aaa58a4c1e58e98963"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_NOREALLOC</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Disable buffer (re)allocation. </p>
-<p>If passed to one of the JPEG compression or transform functions, this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga43b426750b46190a25d34a67ef76df1b"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_PROGRESSIVE</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Use progressive entropy coding in JPEG images generated by the compression and transform functions. </p>
-<p>Progressive entropy coding will generally improve compression relative to baseline entropy coding (the default), but it will reduce compression and decompression performance considerably. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga519cfa4ef6c18d9e5b455fdf59306a3a"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJFLAG_STOPONWARNING</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Immediately discontinue the current compression/decompression/transform operation if the underlying codec throws a warning (non-fatal error). </p>
-<p>The default behavior is to allow the operation to complete unless a fatal error is encountered. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga0aba955473315e405295d978f0c16511"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJPAD</td>
-          <td>(</td>
-          <td class="paramtype">&#160;</td>
-          <td class="paramname">width</td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Pad the given width to the nearest 32-bit boundary. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga84878bb65404204743aa18cac02781df"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJSCALED</td>
-          <td>(</td>
-          <td class="paramtype">&#160;</td>
-          <td class="paramname">dimension, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">&#160;</td>
-          <td class="paramname">scalingFactor&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Compute the scaled value of <code>dimension</code> using the given scaling factor. </p>
-<p>This macro performs the integer equivalent of <code>ceil(dimension * scalingFactor)</code>. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga153b468cfb905d0de61706c838986fe8"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_COPYNONE</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will prevent <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> from copying any extra markers (including EXIF and ICC profile data) from the source image to the output image. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga9c771a757fc1294add611906b89ab2d2"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_CROP</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will enable lossless cropping. </p>
-<p>See <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> for more information. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga3acee7b48ade1b99e5588736007c2589"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_GRAY</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will discard the color data in the input image and produce a grayscale output image. </p>
-
-</div>
-</div>
-<a class="anchor" id="gafbf992bbf6e006705886333703ffab31"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_NOOUTPUT</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will prevent <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> from outputting a JPEG image for this particular transform (this can be used in conjunction with a custom filter to capture the transformed DCT coefficients without transcoding them.) </p>
-
-</div>
-</div>
-<a class="anchor" id="ga50e03cb5ed115330e212417429600b00"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_PERFECT</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will cause <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> to return an error if the transform is not perfect. </p>
-<p>Lossless transforms operate on MCU blocks, whose size depends on the level of chrominance subsampling used (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a> and <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>.) If the image's width or height is not evenly divisible by the MCU block size, then there will be partial MCU blocks on the right and/or bottom edges. It is not possible to move these partial MCU blocks to the top or left of the image, so any transform that would require that is "imperfect." If this option is not specified, then any partial MCU blocks that cannot be transformed will be left in place, which will create odd-looking strips on the right or bottom edge of the image. </p>
-
-</div>
-</div>
-<a class="anchor" id="gad2371c80674584ecc1a7d75e564cf026"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_PROGRESSIVE</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will enable progressive entropy coding in the output image generated by this particular transform. </p>
-<p>Progressive entropy coding will generally improve compression relative to baseline entropy coding (the default), but it will reduce compression and decompression performance considerably. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga319826b7eb1583c0595bbe7b95428709"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">#define TJXOPT_TRIM</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>This option will cause <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> to discard any partial MCU blocks that cannot be transformed. </p>
-
-</div>
-</div>
-<h2 class="groupheader">Typedef Documentation</h2>
-<a class="anchor" id="ga758d2634ecb4949de7815cba621f5763"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef void* <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>TurboJPEG instance handle. </p>
-
-</div>
-</div>
-<a class="anchor" id="gaa29f3189c41be12ec5dee7caec318a31"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">typedef struct <a class="el" href="structtjtransform.html">tjtransform</a>  <a class="el" href="structtjtransform.html">tjtransform</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Lossless transform. </p>
-
-</div>
-</div>
-<h2 class="groupheader">Enumeration Type Documentation</h2>
-<a class="anchor" id="ga4f83ad3368e0e29d1957be0efa7c3720"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720">TJCS</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>JPEG colorspaces. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><em><a class="anchor" id="gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555"></a>TJCS_RGB</em>&nbsp;</td><td class="fielddoc">
-<p>RGB colorspace. </p>
-<p>When compressing the JPEG image, the R, G, and B components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. RGB JPEG images can be decompressed to any of the extended RGB pixel formats or grayscale, but they cannot be decompressed to YUV images. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75"></a>TJCS_YCbCr</em>&nbsp;</td><td class="fielddoc">
-<p>YCbCr colorspace. </p>
-<p>YCbCr is not an absolute colorspace but rather a mathematical transformation of RGB designed solely for storage and transmission. YCbCr images must be converted to RGB before they can actually be displayed. In the YCbCr colorspace, the Y (luminance) component represents the black &amp; white portion of the original image, and the Cb and Cr (chrominance) components represent the color portion of the original image. Originally, the analog equivalent of this transformation allowed the same signal to drive both black &amp; white and color televisions, but JPEG images use YCbCr primarily because it allows the color data to be optionally subsampled for the purposes of reducing bandwidth or disk space. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images can be compressed from and decompressed to any of the extended RGB pixel formats or grayscale, or they can be decompressed to YUV planar images. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a"></a>TJCS_GRAY</em>&nbsp;</td><td class="fielddoc">
-<p>Grayscale colorspace. </p>
-<p>The JPEG image retains only the luminance data (Y component), and any color data from the source image is discarded. Grayscale JPEG images can be compressed from and decompressed to any of the extended RGB pixel formats or grayscale, or they can be decompressed to YUV planar images. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53"></a>TJCS_CMYK</em>&nbsp;</td><td class="fielddoc">
-<p>CMYK colorspace. </p>
-<p>When compressing the JPEG image, the C, M, Y, and K components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. CMYK JPEG images can only be decompressed to CMYK pixels. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e"></a>TJCS_YCCK</em>&nbsp;</td><td class="fielddoc">
-<p>YCCK colorspace. </p>
-<p>YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a mathematical transformation of CMYK designed solely for storage and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be reversibly transformed into YCCK, and as with YCbCr, the chrominance components in the YCCK pixels can be subsampled without incurring major perceptual loss. YCCK JPEG images can only be compressed from and decompressed to CMYK pixels. </p>
-</td></tr>
-</table>
-
-</div>
-</div>
-<a class="anchor" id="gafbc17cfa57d0d5d11fea35ac025950fe"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe">TJERR</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Error codes. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><em><a class="anchor" id="ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59"></a>TJERR_WARNING</em>&nbsp;</td><td class="fielddoc">
-<p>The error was non-fatal and recoverable, but the image may still be corrupt. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a"></a>TJERR_FATAL</em>&nbsp;</td><td class="fielddoc">
-<p>The error was fatal and non-recoverable. </p>
-</td></tr>
-</table>
-
-</div>
-</div>
-<a class="anchor" id="gac916144e26c3817ac514e64ae5d12e2a"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">TJPF</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Pixel formats. </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c"></a>TJPF_RGB</em>&nbsp;</td><td class="fielddoc">
-<p>RGB pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 3-byte pixels in the order R, G, B from lowest to highest byte address within each pixel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839"></a>TJPF_BGR</em>&nbsp;</td><td class="fielddoc">
-<p>BGR pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 3-byte pixels in the order B, G, R from lowest to highest byte address within each pixel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01"></a>TJPF_RGBX</em>&nbsp;</td><td class="fielddoc">
-<p>RGBX pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 4-byte pixels in the order R, G, B from lowest to highest byte address within each pixel. The X component is ignored when compressing and undefined when decompressing. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8"></a>TJPF_BGRX</em>&nbsp;</td><td class="fielddoc">
-<p>BGRX pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 4-byte pixels in the order B, G, R from lowest to highest byte address within each pixel. The X component is ignored when compressing and undefined when decompressing. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af"></a>TJPF_XBGR</em>&nbsp;</td><td class="fielddoc">
-<p>XBGR pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 4-byte pixels in the order R, G, B from highest to lowest byte address within each pixel. The X component is ignored when compressing and undefined when decompressing. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84"></a>TJPF_XRGB</em>&nbsp;</td><td class="fielddoc">
-<p>XRGB pixel format. </p>
-<p>The red, green, and blue components in the image are stored in 4-byte pixels in the order B, G, R from highest to lowest byte address within each pixel. The X component is ignored when compressing and undefined when decompressing. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a"></a>TJPF_GRAY</em>&nbsp;</td><td class="fielddoc">
-<p>Grayscale pixel format. </p>
-<p>Each 1-byte pixel represents a luminance (brightness) level from 0 to 255. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12"></a>TJPF_RGBA</em>&nbsp;</td><td class="fielddoc">
-<p>RGBA pixel format. </p>
-<p>This is the same as <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01">TJPF_RGBX</a>, except that when decompressing, the X component is guaranteed to be 0xFF, which can be interpreted as an opaque alpha channel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4"></a>TJPF_BGRA</em>&nbsp;</td><td class="fielddoc">
-<p>BGRA pixel format. </p>
-<p>This is the same as <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8">TJPF_BGRX</a>, except that when decompressing, the X component is guaranteed to be 0xFF, which can be interpreted as an opaque alpha channel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081"></a>TJPF_ABGR</em>&nbsp;</td><td class="fielddoc">
-<p>ABGR pixel format. </p>
-<p>This is the same as <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af">TJPF_XBGR</a>, except that when decompressing, the X component is guaranteed to be 0xFF, which can be interpreted as an opaque alpha channel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c"></a>TJPF_ARGB</em>&nbsp;</td><td class="fielddoc">
-<p>ARGB pixel format. </p>
-<p>This is the same as <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84">TJPF_XRGB</a>, except that when decompressing, the X component is guaranteed to be 0xFF, which can be interpreted as an opaque alpha channel. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b"></a>TJPF_CMYK</em>&nbsp;</td><td class="fielddoc">
-<p>CMYK pixel format. </p>
-<p>Unlike RGB, which is an additive color model used primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive color model used primarily for printing. In the CMYK color model, the value of each color component typically corresponds to an amount of cyan, magenta, yellow, or black ink that is applied to a white background. In order to convert between CMYK and RGB, it is necessary to use a color management system (CMS.) A CMS will attempt to map colors within the printer's gamut to perceptually similar colors in the display's gamut and vice versa, but the mapping is typically not 1:1 or reversible, nor can it be defined with a simple formula. Thus, such a conversion is out of scope for a codec library. However, the TurboJPEG API allows for compressing CMYK pixels into a YCCK JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e" title="YCCK colorspace.">TJCS_YCCK</a>) and decompressing YCCK JPEG images into CMYK pixels. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed"></a>TJPF_UNKNOWN</em>&nbsp;</td><td class="fielddoc">
-<p>Unknown pixel format. </p>
-<p>Currently this is only used by <a class="el" href="group___turbo_j_p_e_g.html#gaffbd83c375e79f5db4b5c5d8ad4466e7" title="Load an uncompressed image from disk into memory.">tjLoadImage()</a>. </p>
-</td></tr>
-</table>
-
-</div>
-</div>
-<a class="anchor" id="ga1d047060ea80bb9820d540bb928e9074"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">TJSAMP</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Chrominance subsampling options. </p>
-<p>When pixels are converted from RGB to YCbCr (see <a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75" title="YCbCr colorspace.">TJCS_YCbCr</a>) or from CMYK to YCCK (see <a class="el" href="group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e" title="YCCK colorspace.">TJCS_YCCK</a>) as part of the JPEG compression process, some of the Cb and Cr (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible loss of image clarity (the human eye is more sensitive to small changes in brightness than to small changes in color.) This is called "chrominance subsampling". </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3"></a>TJSAMP_444</em>&nbsp;</td><td class="fielddoc">
-<p>4:4:4 chrominance subsampling (no chrominance subsampling). </p>
-<p>The JPEG or YUV image will contain one chrominance component for every pixel in the source image. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404"></a>TJSAMP_422</em>&nbsp;</td><td class="fielddoc">
-<p>4:2:2 chrominance subsampling. </p>
-<p>The JPEG or YUV image will contain one chrominance component for every 2x1 block of pixels in the source image. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737"></a>TJSAMP_420</em>&nbsp;</td><td class="fielddoc">
-<p>4:2:0 chrominance subsampling. </p>
-<p>The JPEG or YUV image will contain one chrominance component for every 2x2 block of pixels in the source image. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248"></a>TJSAMP_GRAY</em>&nbsp;</td><td class="fielddoc">
-<p>Grayscale. </p>
-<p>The JPEG or YUV image will contain no chrominance components. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974"></a>TJSAMP_440</em>&nbsp;</td><td class="fielddoc">
-<p>4:4:0 chrominance subsampling. </p>
-<p>The JPEG or YUV image will contain one chrominance component for every 1x2 block of pixels in the source image.</p>
-<dl class="section note"><dt>Note</dt><dd>4:4:0 subsampling is not fully accelerated in libjpeg-turbo. </dd></dl>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2"></a>TJSAMP_411</em>&nbsp;</td><td class="fielddoc">
-<p>4:1:1 chrominance subsampling. </p>
-<p>The JPEG or YUV image will contain one chrominance component for every 4x1 block of pixels in the source image. JPEG images compressed with 4:1:1 subsampling will be almost exactly the same size as those compressed with 4:2:0 subsampling, and in the aggregate, both subsampling methods produce approximately the same perceptual quality. However, 4:1:1 is better able to reproduce sharp horizontal features.</p>
-<dl class="section note"><dt>Note</dt><dd>4:1:1 subsampling is not fully accelerated in libjpeg-turbo. </dd></dl>
-</td></tr>
-</table>
-
-</div>
-</div>
-<a class="anchor" id="ga2de531af4e7e6c4f124908376b354866"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">enum <a class="el" href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">TJXOP</a></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Transform operations for <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> </p>
-<table class="fieldtable">
-<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27"></a>TJXOP_NONE</em>&nbsp;</td><td class="fielddoc">
-<p>Do not transform the position of the image pixels. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce"></a>TJXOP_HFLIP</em>&nbsp;</td><td class="fielddoc">
-<p>Flip (mirror) image horizontally. </p>
-<p>This transform is imperfect if there are any partial MCU blocks on the right edge (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d"></a>TJXOP_VFLIP</em>&nbsp;</td><td class="fielddoc">
-<p>Flip (mirror) image vertically. </p>
-<p>This transform is imperfect if there are any partial MCU blocks on the bottom edge (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d"></a>TJXOP_TRANSPOSE</em>&nbsp;</td><td class="fielddoc">
-<p>Transpose image (flip/mirror along upper left to lower right axis.) This transform is always perfect. </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4"></a>TJXOP_TRANSVERSE</em>&nbsp;</td><td class="fielddoc">
-<p>Transverse transpose image (flip/mirror along upper right to lower left axis.) This transform is imperfect if there are any partial MCU blocks in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128"></a>TJXOP_ROT90</em>&nbsp;</td><td class="fielddoc">
-<p>Rotate image clockwise by 90 degrees. </p>
-<p>This transform is imperfect if there are any partial MCU blocks on the bottom edge (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692"></a>TJXOP_ROT180</em>&nbsp;</td><td class="fielddoc">
-<p>Rotate image 180 degrees. </p>
-<p>This transform is imperfect if there are any partial MCU blocks in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-<tr><td class="fieldname"><em><a class="anchor" id="gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08"></a>TJXOP_ROT270</em>&nbsp;</td><td class="fielddoc">
-<p>Rotate image counter-clockwise by 90 degrees. </p>
-<p>This transform is imperfect if there are any partial MCU blocks on the right edge (see <a class="el" href="group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00" title="This option will cause tjTransform() to return an error if the transform is not perfect.">TJXOPT_PERFECT</a>.) </p>
-</td></tr>
-</table>
-
-</div>
-</div>
-<h2 class="groupheader">Function Documentation</h2>
-<a class="anchor" id="gaec627dd4c5f30b7a775a7aea3bec5d83"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT unsigned char* tjAlloc </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>bytes</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Allocate an image buffer for use with TurboJPEG. </p>
-<p>You should always use this function to allocate the JPEG destination buffer(s) for the compression and transform functions unless you are disabling automatic buffer (re)allocation (by setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>.)</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">bytes</td><td>the number of bytes to allocate</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>a pointer to a newly-allocated buffer with the specified number of bytes.</dd></dl>
-<dl class="section see"><dt>See Also</dt><dd><a class="el" href="group___turbo_j_p_e_g.html#gaea863d2da0cdb609563aabdf9196514b" title="Free an image buffer previously allocated by TurboJPEG.">tjFree()</a> </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga67ac12fee79073242cb216e07c9f1f90"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT unsigned long tjBufSize </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>jpegSubsamp</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters. </p>
-<p>The number of bytes returned by this function is larger than the size of the uncompressed source image. The reason for this is that the JPEG format uses 16-bit coefficients, and it is thus possible for a very high-quality JPEG image with very high-frequency content to expand rather than compress when converted to the JPEG format. Such images represent a very rare corner case, but since there is no way to predict the size of a JPEG image prior to compression, the corner case has to be handled.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">width</td><td>width (in pixels) of the image</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the image</td></tr>
-    <tr><td class="paramname">jpegSubsamp</td><td>the level of chrominance subsampling to be used when generating the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>the maximum size of the buffer (in bytes) required to hold the image, or -1 if the arguments are out of bounds. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga2be2b9969d4df9ecce9b05deed273194"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT unsigned long tjBufSizeYUV2 </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pad</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">width</td><td>width (in pixels) of the image</td></tr>
-    <tr><td class="paramname">pad</td><td>the width of each line in each plane of the image is padded to the nearest multiple of this number of bytes (must be a power of 2.)</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the image</td></tr>
-    <tr><td class="paramname">subsamp</td><td>level of chrominance subsampling in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>the size of the buffer (in bytes) required to hold the image, or -1 if the arguments are out of bounds. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gafbdce0112fd78fd38efae841443a9bcf"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjCompress2 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>srcBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long *&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>jpegSubsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>jpegQual</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Compress an RGB, grayscale, or CMYK image into a JPEG image. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcBuf</td><td>pointer to an image buffer containing RGB, grayscale, or CMYK pixels to be compressed</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the source image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the source image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
-<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
-<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
-<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
-</ol>
-If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
-    <tr><td class="paramname">jpegSubsamp</td><td>the level of chrominance subsampling to be used when generating the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga7622a459b79aa1007e005b58783f875b"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjCompressFromYUV </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>srcBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pad</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long *&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>jpegQual</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Compress a YUV planar image into a JPEG image. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcBuf</td><td>pointer to an image buffer containing a YUV planar image to be compressed. The size of this buffer should match the value returned by <a class="el" href="group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> for the given image width, height, padding, and level of chrominance subsampling. The Y, U (Cb), and V (Cr) image planes should be stored sequentially in the source buffer (refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.)</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source image. If the width is not an even multiple of the MCU block width (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">pad</td><td>the line padding used in the source image. For instance, if each line in each plane of the YUV image is padded to the nearest multiple of 4 bytes, then <code>pad</code> should be set to 4.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source image. If the height is not an even multiple of the MCU block height (see <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling used in the source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
-<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
-<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
-<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
-</ol>
-If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
-    <tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga29ec5dfbd2d84b8724e951d6fa0d5d9e"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjCompressFromYUVPlanes </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char **&#160;</td>
-          <td class="paramname"><em>srcPlanes</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const int *&#160;</td>
-          <td class="paramname"><em>strides</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long *&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>jpegQual</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Compress a set of Y, U (Cb), and V (Cr) image planes into a JPEG image. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcPlanes</td><td>an array of pointers to Y, U (Cb), and V (Cr) image planes (or just a Y plane, if compressing a grayscale image) that contain a YUV image to be compressed. These planes can be contiguous or non-contiguous in memory. The size of each plane should match the value returned by <a class="el" href="group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d" title="The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters...">tjPlaneSizeYUV()</a> for the given image width, height, strides, and level of chrominance subsampling. Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for more details.</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source image. If the width is not an even multiple of the MCU block width (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">strides</td><td>an array of integers, each specifying the number of bytes per line in the corresponding plane of the YUV source image. Setting the stride for any plane to 0 is the same as setting it to the plane width (see <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.) If <code>strides</code> is NULL, then the strides for all planes will be set to their respective plane widths. You can adjust the strides in order to specify an arbitrary amount of line padding in each plane or to create a JPEG image from a subregion of a larger YUV planar image.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source image. If the height is not an even multiple of the MCU block height (see <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling used in the source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
-<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
-<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
-<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
-</ol>
-If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
-    <tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga70abbf38f77a26fd6da8813bef96f695"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecodeYUV </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>srcBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pad</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>dstBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Decode a YUV planar image into an RGB or grayscale image. </p>
-<p>This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG decompression process.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcBuf</td><td>pointer to an image buffer containing a YUV planar image to be decoded. The size of this buffer should match the value returned by <a class="el" href="group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> for the given image width, height, padding, and level of chrominance subsampling. The Y, U (Cb), and V (Cr) image planes should be stored sequentially in the source buffer (refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.)</td></tr>
-    <tr><td class="paramname">pad</td><td>Use this parameter to specify that the width of each line in each plane of the YUV source image is padded to the nearest multiple of this number of bytes (must be a power of 2.)</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling used in the YUV source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the decoded image. This buffer should normally be <code>pitch * height</code> bytes in size, but the <code>dstBuf</code> pointer can also be used to decode into a specific region of a larger buffer.</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source and destination images</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the destination image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the destination image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the destination image should be padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use the pitch parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source and destination images</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the destination image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga10e837c07fa9d25770565b237d3898d9"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecodeYUVPlanes </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char **&#160;</td>
-          <td class="paramname"><em>srcPlanes</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const int *&#160;</td>
-          <td class="paramname"><em>strides</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>dstBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Decode a set of Y, U (Cb), and V (Cr) image planes into an RGB or grayscale image. </p>
-<p>This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG decompression process.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcPlanes</td><td>an array of pointers to Y, U (Cb), and V (Cr) image planes (or just a Y plane, if decoding a grayscale image) that contain a YUV image to be decoded. These planes can be contiguous or non-contiguous in memory. The size of each plane should match the value returned by <a class="el" href="group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d" title="The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters...">tjPlaneSizeYUV()</a> for the given image width, height, strides, and level of chrominance subsampling. Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for more details.</td></tr>
-    <tr><td class="paramname">strides</td><td>an array of integers, each specifying the number of bytes per line in the corresponding plane of the YUV source image. Setting the stride for any plane to 0 is the same as setting it to the plane width (see <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.) If <code>strides</code> is NULL, then the strides for all planes will be set to their respective plane widths. You can adjust the strides in order to specify an arbitrary amount of line padding in each plane or to decode a subregion of a larger YUV planar image.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling used in the YUV source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the decoded image. This buffer should normally be <code>pitch * height</code> bytes in size, but the <code>dstBuf</code> pointer can also be used to decode into a specific region of a larger buffer.</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source and destination images</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the destination image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the destination image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the destination image should be padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use the pitch parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source and destination images</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the destination image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gae9eccef8b682a48f43a9117c231ed013"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecompress2 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>dstBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Decompress a JPEG image to an RGB, grayscale, or CMYK image. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing the JPEG image to decompress</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>size of the JPEG image (in bytes)</td></tr>
-    <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the decompressed image. This buffer should normally be <code>pitch * scaledHeight</code> bytes in size, where <code>scaledHeight</code> can be determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df" title="Compute the scaled value of dimension using the given scaling factor.">TJSCALED()</a> with the JPEG image height and one of the scaling factors returned by <a class="el" href="group___turbo_j_p_e_g.html#gac3854476006b10787bd128f7ede48057" title="Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of Tur...">tjGetScalingFactors()</a>. The <code>dstBuf</code> pointer may also be used to decompress into a specific region of a larger buffer.</td></tr>
-    <tr><td class="paramname">width</td><td>desired width (in pixels) of the destination image. If this is different than the width of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired width. If <code>width</code> is set to 0, then only the height will be considered when determining the scaled image size.</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the destination image. Normally, this is <code>scaledWidth * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the decompressed image is unpadded, else <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(scaledWidth * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the decompressed image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. (NOTE: <code>scaledWidth</code> can be determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df" title="Compute the scaled value of dimension using the given scaling factor.">TJSCALED()</a> with the JPEG image width and one of the scaling factors returned by <a class="el" href="group___turbo_j_p_e_g.html#gac3854476006b10787bd128f7ede48057" title="Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of Tur...">tjGetScalingFactors()</a>.) You can also be clever and use the pitch parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>scaledWidth * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>desired height (in pixels) of the destination image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If <code>height</code> is set to 0, then only the width will be considered when determining the scaled image size.</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the destination image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga0595681096bba7199cc6f3533cb25f77"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecompressHeader3 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>jpegSubsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>jpegColorspace</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Retrieve information about a JPEG image without decompressing it. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing a JPEG image</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>size of the JPEG image (in bytes)</td></tr>
-    <tr><td class="paramname">width</td><td>pointer to an integer variable that will receive the width (in pixels) of the JPEG image</td></tr>
-    <tr><td class="paramname">height</td><td>pointer to an integer variable that will receive the height (in pixels) of the JPEG image</td></tr>
-    <tr><td class="paramname">jpegSubsamp</td><td>pointer to an integer variable that will receive the level of chrominance subsampling used when the JPEG image was compressed (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-    <tr><td class="paramname">jpegColorspace</td><td>pointer to an integer variable that will receive one of the JPEG colorspace constants, indicating the colorspace of the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720">JPEG colorspaces</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga04d1e839ff9a0860dd1475cff78d3364"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecompressToYUV2 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>dstBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pad</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Decompress a JPEG image to a YUV planar image. </p>
-<p>This function performs JPEG decompression but leaves out the color conversion step, so a planar YUV image is generated instead of an RGB image.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing the JPEG image to decompress</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>size of the JPEG image (in bytes)</td></tr>
-    <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> to determine the appropriate size for this buffer based on the image width, height, padding, and level of subsampling. The Y, U (Cb), and V (Cr) image planes will be stored sequentially in the buffer (refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.)</td></tr>
-    <tr><td class="paramname">width</td><td>desired width (in pixels) of the YUV image. If this is different than the width of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired width. If <code>width</code> is set to 0, then only the height will be considered when determining the scaled image size. If the scaled width is not an even multiple of the MCU block width (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">pad</td><td>the width of each line in each plane of the YUV image will be padded to the nearest multiple of this number of bytes (must be a power of 2.) To generate images suitable for X Video, <code>pad</code> should be set to 4.</td></tr>
-    <tr><td class="paramname">height</td><td>desired height (in pixels) of the YUV image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If <code>height</code> is set to 0, then only the width will be considered when determining the scaled image size. If the scaled height is not an even multiple of the MCU block height (see <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gaa59f901a5258ada5bd0185ad59368540"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDecompressToYUVPlanes </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>dstPlanes</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>strides</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Decompress a JPEG image into separate Y, U (Cb), and V (Cr) image planes. </p>
-<p>This function performs JPEG decompression but leaves out the color conversion step, so a planar YUV image is generated instead of an RGB image.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG decompressor or transformer instance</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing the JPEG image to decompress</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>size of the JPEG image (in bytes)</td></tr>
-    <tr><td class="paramname">dstPlanes</td><td>an array of pointers to Y, U (Cb), and V (Cr) image planes (or just a Y plane, if decompressing a grayscale image) that will receive the YUV image. These planes can be contiguous or non-contiguous in memory. Use <a class="el" href="group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d" title="The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters...">tjPlaneSizeYUV()</a> to determine the appropriate size for each plane based on the scaled image width, scaled image height, strides, and level of chrominance subsampling. Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for more details.</td></tr>
-    <tr><td class="paramname">width</td><td>desired width (in pixels) of the YUV image. If this is different than the width of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired width. If <code>width</code> is set to 0, then only the height will be considered when determining the scaled image size. If the scaled width is not an even multiple of the MCU block width (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">strides</td><td>an array of integers, each specifying the number of bytes per line in the corresponding plane of the output image. Setting the stride for any plane to 0 is the same as setting it to the scaled plane width (see <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.) If <code>strides</code> is NULL, then the strides for all planes will be set to their respective scaled plane widths. You can adjust the strides in order to add an arbitrary amount of line padding to each plane or to decompress the JPEG image into a subregion of a larger YUV planar image.</td></tr>
-    <tr><td class="paramname">height</td><td>desired height (in pixels) of the YUV image. If this is different than the height of the JPEG image being decompressed, then TurboJPEG will use scaling in the JPEG decompressor to generate the largest possible image that will fit within the desired height. If <code>height</code> is set to 0, then only the width will be considered when determining the scaled image size. If the scaled height is not an even multiple of the MCU block height (see <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>), then an intermediate buffer copy will be performed within TurboJPEG.</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga75f355fa27225ba1a4ee392c852394d2"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjDestroy </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Destroy a TurboJPEG compressor, decompressor, or transformer instance. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor, decompressor or transformer instance</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gac519b922cdf446e97d0cdcba513636bf"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjEncodeYUV3 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>srcBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>dstBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pad</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Encode an RGB or grayscale image into a YUV planar image. </p>
-<p>This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG compression process.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcBuf</td><td>pointer to an image buffer containing RGB or grayscale pixels to be encoded</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the source image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the source image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">dstBuf</td><td>pointer to an image buffer that will receive the YUV image. Use <a class="el" href="group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194" title="The size of the buffer (in bytes) required to hold a YUV planar image with the given parameters...">tjBufSizeYUV2()</a> to determine the appropriate size for this buffer based on the image width, height, padding, and level of chrominance subsampling. The Y, U (Cb), and V (Cr) image planes will be stored sequentially in the buffer (refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.)</td></tr>
-    <tr><td class="paramname">pad</td><td>the width of each line in each plane of the YUV image will be padded to the nearest multiple of this number of bytes (must be a power of 2.) To generate images suitable for X Video, <code>pad</code> should be set to 4.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling to be used when generating the YUV image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.) To generate images suitable for X Video, <code>subsamp</code> should be set to <a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737">TJSAMP_420</a>. This produces an image compatible with the I420 (AKA "YUV420P") format.</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gae2d04c72457fe7f4d60cf78ab1b1feb1"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjEncodeYUVPlanes </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>srcBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>dstPlanes</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>strides</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Encode an RGB or grayscale image into separate Y, U (Cb), and V (Cr) image planes. </p>
-<p>This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG compression process.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor or transformer instance</td></tr>
-    <tr><td class="paramname">srcBuf</td><td>pointer to an image buffer containing RGB or grayscale pixels to be encoded</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the source image. Normally, this should be <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code> if the image is unpadded, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511" title="Pad the given width to the nearest 32-bit boundary.">TJPAD</a>(width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat])</code> if each line of the image is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use this parameter to skip lines, etc. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the source image</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the source image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.)</td></tr>
-    <tr><td class="paramname">dstPlanes</td><td>an array of pointers to Y, U (Cb), and V (Cr) image planes (or just a Y plane, if generating a grayscale image) that will receive the encoded image. These planes can be contiguous or non-contiguous in memory. Use <a class="el" href="group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d" title="The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters...">tjPlaneSizeYUV()</a> to determine the appropriate size for each plane based on the image width, height, strides, and level of chrominance subsampling. Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for more details.</td></tr>
-    <tr><td class="paramname">strides</td><td>an array of integers, each specifying the number of bytes per line in the corresponding plane of the output image. Setting the stride for any plane to 0 is the same as setting it to the plane width (see <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a>.) If <code>strides</code> is NULL, then the strides for all planes will be set to their respective plane widths. You can adjust the strides in order to add an arbitrary amount of line padding to each plane or to encode an RGB or grayscale image into a subregion of a larger YUV planar image.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>the level of chrominance subsampling to be used when generating the YUV image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.) To generate images suitable for X Video, <code>subsamp</code> should be set to <a class="el" href="group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737">TJSAMP_420</a>. This produces an image compatible with the I420 (AKA "YUV420P") format.</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gaea863d2da0cdb609563aabdf9196514b"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT void tjFree </td>
-          <td>(</td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>buffer</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Free an image buffer previously allocated by TurboJPEG. </p>
-<p>You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by the compression and transform functions or that were manually allocated using <a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a>.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">buffer</td><td>address of the buffer to free</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section see"><dt>See Also</dt><dd><a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga414feeffbf860ebd31c745df203de410"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjGetErrorCode </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Returns a code indicating the severity of the last error. </p>
-<p>See <a class="el" href="group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe">Error codes</a>.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor, decompressor or transformer instance</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>a code indicating the severity of the last error. See <a class="el" href="group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe">Error codes</a>. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga1ead8574f9f39fbafc6b497124e7aafa"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT char* tjGetErrorStr2 </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Returns a descriptive error message explaining why the last command failed. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor, decompressor, or transformer instance, or NULL if the error was generated by a global function (but note that retrieving the error message for a global function is not thread-safe.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>a descriptive error message explaining why the last command failed. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gac3854476006b10787bd128f7ede48057"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT <a class="el" href="structtjscalingfactor.html">tjscalingfactor</a>* tjGetScalingFactors </td>
-          <td>(</td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>numscalingfactors</em></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of TurboJPEG supports. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">numscalingfactors</td><td>pointer to an integer variable that will receive the number of elements in the list</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga9d63a05fc6d813f4aae06107041a37e8"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> tjInitCompress </td>
-          <td>(</td>
-          <td class="paramtype">void&#160;</td>
-          <td class="paramname"></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Create a TurboJPEG compressor instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga52300eac3f3d9ef4bab303bc244f62d3"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> tjInitDecompress </td>
-          <td>(</td>
-          <td class="paramtype">void&#160;</td>
-          <td class="paramname"></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Create a TurboJPEG decompressor instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga928beff6ac248ceadf01089fc6b41957"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT <a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> tjInitTransform </td>
-          <td>(</td>
-          <td class="paramtype">void&#160;</td>
-          <td class="paramname"></td><td>)</td>
-          <td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Create a new TurboJPEG transformer instance. </p>
-<dl class="section return"><dt>Returns</dt><dd>a handle to the newly-created instance, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gaffbd83c375e79f5db4b5c5d8ad4466e7"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT unsigned char* tjLoadImage </td>
-          <td>(</td>
-          <td class="paramtype">const char *&#160;</td>
-          <td class="paramname"><em>filename</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>align</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int *&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Load an uncompressed image from disk into memory. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">filename</td><td>name of a file containing an uncompressed image in Windows BMP or PBMPLUS (PPM/PGM) format</td></tr>
-    <tr><td class="paramname">width</td><td>pointer to an integer variable that will receive the width (in pixels) of the uncompressed image</td></tr>
-    <tr><td class="paramname">align</td><td>row alignment of the image buffer to be returned (must be a power of 2.) For instance, setting this parameter to 4 will cause all rows in the image buffer to be padded to the nearest 32-bit boundary, and setting this parameter to 1 will cause all rows in the image buffer to be unpadded.</td></tr>
-    <tr><td class="paramname">height</td><td>pointer to an integer variable that will receive the height (in pixels) of the uncompressed image</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pointer to an integer variable that specifies or will receive the pixel format of the uncompressed image buffer. The behavior of <a class="el" href="group___turbo_j_p_e_g.html#gaffbd83c375e79f5db4b5c5d8ad4466e7" title="Load an uncompressed image from disk into memory.">tjLoadImage()</a> will vary depending on the value of <code>*pixelFormat</code> passed to the function:<ul>
-<li><a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed">TJPF_UNKNOWN</a> : The uncompressed image buffer returned by the function will use the most optimal pixel format for the file type, and <code>*pixelFormat</code> will contain the ID of this pixel format upon successful return from the function.</li>
-<li><a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a> : Only PGM files and 8-bit BMP files with a grayscale colormap can be loaded.</li>
-<li><a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a> : The RGB or grayscale pixels stored in the file will be converted using a quick &amp; dirty algorithm that is suitable only for testing purposes (proper conversion between CMYK and other formats requires a color management system.)</li>
-<li>Other <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">pixel formats</a> : The uncompressed image buffer will use the specified pixel format, and pixel format conversion will be performed if necessary.</li>
-</ul>
-</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a>.</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>a pointer to a newly-allocated buffer containing the uncompressed image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) This buffer should be freed using <a class="el" href="group___turbo_j_p_e_g.html#gaea863d2da0cdb609563aabdf9196514b" title="Free an image buffer previously allocated by TurboJPEG.">tjFree()</a>. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga1a209696c6a80748f20e134b3c64789f"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjPlaneHeight </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>componentID</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The plane height of a YUV image plane with the given parameters. </p>
-<p>Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for a description of plane height.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">componentID</td><td>ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr)</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the YUV image</td></tr>
-    <tr><td class="paramname">subsamp</td><td>level of chrominance subsampling in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>the plane height of a YUV image plane with the given parameters, or -1 if the arguments are out of bounds. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="gab4ab7b24f6e797d79abaaa670373961d"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT unsigned long tjPlaneSizeYUV </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>componentID</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>stride</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">componentID</td><td>ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr)</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the YUV image. NOTE: this is the width of the whole image, not the plane width.</td></tr>
-    <tr><td class="paramname">stride</td><td>bytes per line in the image plane. Setting this to 0 is the equivalent of setting it to the plane width.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the YUV image. NOTE: this is the height of the whole image, not the plane height.</td></tr>
-    <tr><td class="paramname">subsamp</td><td>level of chrominance subsampling in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>the size of the buffer (in bytes) required to hold the YUV image plane, or -1 if the arguments are out of bounds. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga63fb66bb1e36c74008c4634360becbb1"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjPlaneWidth </td>
-          <td>(</td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>componentID</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>subsamp</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The plane width of a YUV image plane with the given parameters. </p>
-<p>Refer to <a class="el" href="group___turbo_j_p_e_g.html#YUVnotes">YUV Image Format Notes</a> for a description of plane width.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">componentID</td><td>ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr)</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the YUV image</td></tr>
-    <tr><td class="paramname">subsamp</td><td>level of chrominance subsampling in the image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>the plane width of a YUV image plane with the given parameters, or -1 if the arguments are out of bounds. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga6f445b22d8933ae4815b3370a538d879"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjSaveImage </td>
-          <td>(</td>
-          <td class="paramtype">const char *&#160;</td>
-          <td class="paramname"><em>filename</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char *&#160;</td>
-          <td class="paramname"><em>buffer</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>width</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pitch</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>height</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>pixelFormat</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Save an uncompressed image from memory to disk. </p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">filename</td><td>name of a file to which to save the uncompressed image. The image will be stored in Windows BMP or PBMPLUS (PPM/PGM) format, depending on the file extension.</td></tr>
-    <tr><td class="paramname">buffer</td><td>pointer to an image buffer containing RGB, grayscale, or CMYK pixels to be saved</td></tr>
-    <tr><td class="paramname">width</td><td>width (in pixels) of the uncompressed image</td></tr>
-    <tr><td class="paramname">pitch</td><td>bytes per line in the image buffer. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in bytes) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
-    <tr><td class="paramname">height</td><td>height (in pixels) of the uncompressed image</td></tr>
-    <tr><td class="paramname">pixelFormat</td><td>pixel format of the image buffer (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM or 8-bit (indexed color) BMP format. Otherwise, the image will be stored in PPM or 24-bit BMP format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing (proper conversion between CMYK and other formats requires a color management system.)</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a>.</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a>.) </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="ga9cb8abf4cc91881e04a0329b2270be25"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">DLLEXPORT int tjTransform </td>
-          <td>(</td>
-          <td class="paramtype"><a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a>&#160;</td>
-          <td class="paramname"><em>handle</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">const unsigned char *&#160;</td>
-          <td class="paramname"><em>jpegBuf</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long&#160;</td>
-          <td class="paramname"><em>jpegSize</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>n</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned char **&#160;</td>
-          <td class="paramname"><em>dstBufs</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">unsigned long *&#160;</td>
-          <td class="paramname"><em>dstSizes</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype"><a class="el" href="structtjtransform.html">tjtransform</a> *&#160;</td>
-          <td class="paramname"><em>transforms</em>, </td>
-        </tr>
-        <tr>
-          <td class="paramkey"></td>
-          <td></td>
-          <td class="paramtype">int&#160;</td>
-          <td class="paramname"><em>flags</em>&#160;</td>
-        </tr>
-        <tr>
-          <td></td>
-          <td>)</td>
-          <td></td><td></td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Losslessly transform a JPEG image into another JPEG image. </p>
-<p>Lossless transforms work by moving the raw DCT coefficients from one JPEG image structure to another without altering the values of the coefficients. While this is typically faster than decompressing the image, transforming it, and re-compressing it, lossless transforms are not free. Each lossless transform requires reading and performing Huffman decoding on all of the coefficients in the source image, regardless of the size of the destination image. Thus, this function provides a means of generating multiple transformed images from the same source or applying multiple transformations simultaneously, in order to eliminate the need to read the source coefficients multiple times.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG transformer instance</td></tr>
-    <tr><td class="paramname">jpegBuf</td><td>pointer to a buffer containing the JPEG source image to transform</td></tr>
-    <tr><td class="paramname">jpegSize</td><td>size of the JPEG source image (in bytes)</td></tr>
-    <tr><td class="paramname">n</td><td>the number of transformed JPEG images to generate</td></tr>
-    <tr><td class="paramname">dstBufs</td><td>pointer to an array of n image buffers. <code>dstBufs[i]</code> will receive a JPEG image that has been transformed using the parameters in <code>transforms[i]</code>. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
-<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
-<li>set <code>dstBufs[i]</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
-<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a> with the transformed or cropped width and height. Under normal circumstances, this should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.) Note, however, that there are some rare cases (such as transforming images with a large amount of embedded EXIF or ICC profile data) in which the output image will be larger than the worst-case size, and <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> cannot be used in those cases.</li>
-</ol>
-If you choose option 1, <code>dstSizes[i]</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>dstBufs[i]</code> upon return from this function, as it may have changed.</td></tr>
-    <tr><td class="paramname">dstSizes</td><td>pointer to an array of n unsigned long variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If <code>dstBufs[i]</code> points to a pre-allocated buffer, then <code>dstSizes[i]</code> should be set to the size of the buffer. Upon return, <code>dstSizes[i]</code> will contain the size of the JPEG image (in bytes.)</td></tr>
-    <tr><td class="paramname">transforms</td><td>pointer to an array of n <a class="el" href="structtjtransform.html" title="Lossless transform.">tjtransform</a> structures, each of which specifies the transform parameters and/or cropping region for the corresponding transformed output image.</td></tr>
-    <tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0">flags</a></td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if successful, or -1 if an error occurred (see <a class="el" href="group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa" title="Returns a descriptive error message explaining why the last command failed.">tjGetErrorStr2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410" title="Returns a code indicating the severity of the last error.">tjGetErrorCode()</a>.) </dd></dl>
-
-</div>
-</div>
-<h2 class="groupheader">Variable Documentation</h2>
-<a class="anchor" id="ga5af0ab065feefd526debf1e20c43e837"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjAlphaOffset[<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>Alpha offset (in bytes) for a given pixel format. </p>
-<p>This specifies the number of bytes that the Alpha component is offset from the start of the pixel. For instance, if a pixel of format TJ_BGRA is stored in <code>char pixel[]</code>, then the alpha component will be <code>pixel[tjAlphaOffset[TJ_BGRA]]</code>. This will be -1 if the pixel format does not have an alpha component. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga84e2e35d3f08025f976ec1ec53693dea"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjBlueOffset[<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>Blue offset (in bytes) for a given pixel format. </p>
-<p>This specifies the number of bytes that the Blue component is offset from the start of the pixel. For instance, if a pixel of format TJ_BGRX is stored in <code>char pixel[]</code>, then the blue component will be <code>pixel[tjBlueOffset[TJ_BGRX]]</code>. This will be -1 if the pixel format does not have a blue component. </p>
-
-</div>
-</div>
-<a class="anchor" id="ga82d6e35da441112a411da41923c0ba2f"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjGreenOffset[<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>Green offset (in bytes) for a given pixel format. </p>
-<p>This specifies the number of bytes that the green component is offset from the start of the pixel. For instance, if a pixel of format TJ_BGRX is stored in <code>char pixel[]</code>, then the green component will be <code>pixel[tjGreenOffset[TJ_BGRX]]</code>. This will be -1 if the pixel format does not have a green component. </p>
-
-</div>
-</div>
-<a class="anchor" id="gabd247bb9fecb393eca57366feb8327bf"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjMCUHeight[<a class="el" href="group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c">TJ_NUMSAMP</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>MCU block height (in pixels) for a given level of chrominance subsampling. </p>
-<p>MCU block sizes:</p>
-<ul>
-<li>8x8 for no subsampling or grayscale</li>
-<li>16x8 for 4:2:2</li>
-<li>8x16 for 4:4:0</li>
-<li>16x16 for 4:2:0</li>
-<li>32x8 for 4:1:1 </li>
-</ul>
-
-</div>
-</div>
-<a class="anchor" id="ga9e61e7cd47a15a173283ba94e781308c"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjMCUWidth[<a class="el" href="group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c">TJ_NUMSAMP</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>MCU block width (in pixels) for a given level of chrominance subsampling. </p>
-<p>MCU block sizes:</p>
-<ul>
-<li>8x8 for no subsampling or grayscale</li>
-<li>16x8 for 4:2:2</li>
-<li>8x16 for 4:4:0</li>
-<li>16x16 for 4:2:0</li>
-<li>32x8 for 4:1:1 </li>
-</ul>
-
-</div>
-</div>
-<a class="anchor" id="gad77cf8fe5b2bfd3cb3f53098146abb4c"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjPixelSize[<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>Pixel size (in bytes) for a given pixel format. </p>
-
-</div>
-</div>
-<a class="anchor" id="gadd9b446742ac8a3923f7992c7988fea8"></a>
-<div class="memitem">
-<div class="memproto">
-<table class="mlabels">
-  <tr>
-  <td class="mlabels-left">
-      <table class="memname">
-        <tr>
-          <td class="memname">const int tjRedOffset[<a class="el" href="group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e">TJ_NUMPF</a>]</td>
-        </tr>
-      </table>
-  </td>
-  <td class="mlabels-right">
-<span class="mlabels"><span class="mlabel">static</span></span>  </td>
-  </tr>
-</table>
-</div><div class="memdoc">
-
-<p>Red offset (in bytes) for a given pixel format. </p>
-<p>This specifies the number of bytes that the red component is offset from the start of the pixel. For instance, if a pixel of format TJ_BGRX is stored in <code>char pixel[]</code>, then the red component will be <code>pixel[tjRedOffset[TJ_BGRX]]</code>. This will be -1 if the pixel format does not have a red component. </p>
-
-</div>
-</div>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/index.html b/src/third_party/libjpeg-turbo/doc/html/index.html
deleted file mode 100644
index a60f4d0..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/index.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Main Page</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="headertitle">
-<div class="title">TurboJPEG Documentation</div>  </div>
-</div><!--header-->
-<div class="contents">
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/jquery.js b/src/third_party/libjpeg-turbo/doc/html/jquery.js
deleted file mode 100644
index 63939e7..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/jquery.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*! jQuery v1.7.1 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function()
-{g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
-f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d
-&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),
-f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
-{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c)
-{if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
diff --git a/src/third_party/libjpeg-turbo/doc/html/modules.html b/src/third_party/libjpeg-turbo/doc/html/modules.html
deleted file mode 100644
index e79f226..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/modules.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: Modules</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li class="current"><a href="modules.html"><span>Modules</span></a></li>
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-</div><!-- top -->
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-<div class="header">
-  <div class="headertitle">
-<div class="title">Modules</div>  </div>
-</div><!--header-->
-<div class="contents">
-<div class="textblock">Here is a list of all modules:</div><div class="directory">
-<table class="directory">
-<tr id="row_0_" class="even"><td class="entry"><img src="ftv2lastnode.png" alt="\" width="16" height="22" /><a class="el" href="group___turbo_j_p_e_g.html" target="_self">TurboJPEG</a></td><td class="desc">TurboJPEG API</td></tr>
-</table>
-</div><!-- directory -->
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/nav_f.png b/src/third_party/libjpeg-turbo/doc/html/nav_f.png
deleted file mode 100644
index 72a58a5..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/nav_f.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/nav_g.png b/src/third_party/libjpeg-turbo/doc/html/nav_g.png
deleted file mode 100644
index 2093a23..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/nav_g.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/nav_h.png b/src/third_party/libjpeg-turbo/doc/html/nav_h.png
deleted file mode 100644
index 33389b1..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/nav_h.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/open.png b/src/third_party/libjpeg-turbo/doc/html/open.png
deleted file mode 100644
index 30f75c7..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/open.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_63.html b/src/third_party/libjpeg-turbo/doc/html/search/all_63.html
deleted file mode 100644
index e7f34db..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_63.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_63.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_63.js b/src/third_party/libjpeg-turbo/doc/html/search/all_63.js
deleted file mode 100644
index 7b058da..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_63.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['customfilter',['customFilter',['../structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_64.html b/src/third_party/libjpeg-turbo/doc/html/search/all_64.html
deleted file mode 100644
index 360601f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_64.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_64.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_64.js b/src/third_party/libjpeg-turbo/doc/html/search/all_64.js
deleted file mode 100644
index e19a050..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_64.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var searchData=
-[
-  ['data',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]],
-  ['denom',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_68.html b/src/third_party/libjpeg-turbo/doc/html/search/all_68.html
deleted file mode 100644
index dec41d6..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_68.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_68.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_68.js b/src/third_party/libjpeg-turbo/doc/html/search/all_68.js
deleted file mode 100644
index 7b17e97..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_68.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['h',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_6e.html b/src/third_party/libjpeg-turbo/doc/html/search/all_6e.html
deleted file mode 100644
index e0fd765..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_6e.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_6e.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_6e.js b/src/third_party/libjpeg-turbo/doc/html/search/all_6e.js
deleted file mode 100644
index 83faa13..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_6e.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['num',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_6f.html b/src/third_party/libjpeg-turbo/doc/html/search/all_6f.html
deleted file mode 100644
index 5e86b03..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_6f.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_6f.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_6f.js b/src/third_party/libjpeg-turbo/doc/html/search/all_6f.js
deleted file mode 100644
index 1cca832..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_6f.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var searchData=
-[
-  ['op',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]],
-  ['options',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_72.html b/src/third_party/libjpeg-turbo/doc/html/search/all_72.html
deleted file mode 100644
index 347b9f6..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_72.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_72.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_72.js b/src/third_party/libjpeg-turbo/doc/html/search/all_72.js
deleted file mode 100644
index 01cde35..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_72.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['r',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_74.html b/src/third_party/libjpeg-turbo/doc/html/search/all_74.html
deleted file mode 100644
index c646aef..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_74.js b/src/third_party/libjpeg-turbo/doc/html/search/all_74.js
deleted file mode 100644
index 5b97c71..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_74.js
+++ /dev/null
@@ -1,102 +0,0 @@
-var searchData=
-[
-  ['tj_5fnumcs',['TJ_NUMCS',['../group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71',1,'turbojpeg.h']]],
-  ['tj_5fnumerr',['TJ_NUMERR',['../group___turbo_j_p_e_g.html#ga79bde1b4a3e2351e00887e47781b966e',1,'turbojpeg.h']]],
-  ['tj_5fnumpf',['TJ_NUMPF',['../group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e',1,'turbojpeg.h']]],
-  ['tj_5fnumsamp',['TJ_NUMSAMP',['../group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c',1,'turbojpeg.h']]],
-  ['tj_5fnumxop',['TJ_NUMXOP',['../group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c',1,'turbojpeg.h']]],
-  ['tjalloc',['tjAlloc',['../group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83',1,'turbojpeg.h']]],
-  ['tjalphaoffset',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]],
-  ['tjblueoffset',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]],
-  ['tjbufsize',['tjBufSize',['../group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90',1,'turbojpeg.h']]],
-  ['tjbufsizeyuv2',['tjBufSizeYUV2',['../group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194',1,'turbojpeg.h']]],
-  ['tjcompress2',['tjCompress2',['../group___turbo_j_p_e_g.html#gafbdce0112fd78fd38efae841443a9bcf',1,'turbojpeg.h']]],
-  ['tjcompressfromyuv',['tjCompressFromYUV',['../group___turbo_j_p_e_g.html#ga7622a459b79aa1007e005b58783f875b',1,'turbojpeg.h']]],
-  ['tjcompressfromyuvplanes',['tjCompressFromYUVPlanes',['../group___turbo_j_p_e_g.html#ga29ec5dfbd2d84b8724e951d6fa0d5d9e',1,'turbojpeg.h']]],
-  ['tjcs',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]],
-  ['tjcs_5fcmyk',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]],
-  ['tjcs_5fgray',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]],
-  ['tjcs_5frgb',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]],
-  ['tjcs_5fycbcr',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]],
-  ['tjcs_5fycck',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]],
-  ['tjdecodeyuv',['tjDecodeYUV',['../group___turbo_j_p_e_g.html#ga70abbf38f77a26fd6da8813bef96f695',1,'turbojpeg.h']]],
-  ['tjdecodeyuvplanes',['tjDecodeYUVPlanes',['../group___turbo_j_p_e_g.html#ga10e837c07fa9d25770565b237d3898d9',1,'turbojpeg.h']]],
-  ['tjdecompress2',['tjDecompress2',['../group___turbo_j_p_e_g.html#gae9eccef8b682a48f43a9117c231ed013',1,'turbojpeg.h']]],
-  ['tjdecompressheader3',['tjDecompressHeader3',['../group___turbo_j_p_e_g.html#ga0595681096bba7199cc6f3533cb25f77',1,'turbojpeg.h']]],
-  ['tjdecompresstoyuv2',['tjDecompressToYUV2',['../group___turbo_j_p_e_g.html#ga04d1e839ff9a0860dd1475cff78d3364',1,'turbojpeg.h']]],
-  ['tjdecompresstoyuvplanes',['tjDecompressToYUVPlanes',['../group___turbo_j_p_e_g.html#gaa59f901a5258ada5bd0185ad59368540',1,'turbojpeg.h']]],
-  ['tjdestroy',['tjDestroy',['../group___turbo_j_p_e_g.html#ga75f355fa27225ba1a4ee392c852394d2',1,'turbojpeg.h']]],
-  ['tjencodeyuv3',['tjEncodeYUV3',['../group___turbo_j_p_e_g.html#gac519b922cdf446e97d0cdcba513636bf',1,'turbojpeg.h']]],
-  ['tjencodeyuvplanes',['tjEncodeYUVPlanes',['../group___turbo_j_p_e_g.html#gae2d04c72457fe7f4d60cf78ab1b1feb1',1,'turbojpeg.h']]],
-  ['tjerr',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]],
-  ['tjerr_5ffatal',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]],
-  ['tjerr_5fwarning',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]],
-  ['tjflag_5faccuratedct',['TJFLAG_ACCURATEDCT',['../group___turbo_j_p_e_g.html#gacb233cfd722d66d1ccbf48a7de81f0e0',1,'turbojpeg.h']]],
-  ['tjflag_5fbottomup',['TJFLAG_BOTTOMUP',['../group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec',1,'turbojpeg.h']]],
-  ['tjflag_5ffastdct',['TJFLAG_FASTDCT',['../group___turbo_j_p_e_g.html#gaabce235db80d3f698b27f36cbd453da2',1,'turbojpeg.h']]],
-  ['tjflag_5ffastupsample',['TJFLAG_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ga4ee4506c81177a06f77e2504a22efd2d',1,'turbojpeg.h']]],
-  ['tjflag_5fnorealloc',['TJFLAG_NOREALLOC',['../group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963',1,'turbojpeg.h']]],
-  ['tjflag_5fprogressive',['TJFLAG_PROGRESSIVE',['../group___turbo_j_p_e_g.html#ga43b426750b46190a25d34a67ef76df1b',1,'turbojpeg.h']]],
-  ['tjflag_5fstoponwarning',['TJFLAG_STOPONWARNING',['../group___turbo_j_p_e_g.html#ga519cfa4ef6c18d9e5b455fdf59306a3a',1,'turbojpeg.h']]],
-  ['tjfree',['tjFree',['../group___turbo_j_p_e_g.html#gaea863d2da0cdb609563aabdf9196514b',1,'turbojpeg.h']]],
-  ['tjgeterrorcode',['tjGetErrorCode',['../group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410',1,'turbojpeg.h']]],
-  ['tjgeterrorstr2',['tjGetErrorStr2',['../group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa',1,'turbojpeg.h']]],
-  ['tjgetscalingfactors',['tjGetScalingFactors',['../group___turbo_j_p_e_g.html#gac3854476006b10787bd128f7ede48057',1,'turbojpeg.h']]],
-  ['tjgreenoffset',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]],
-  ['tjhandle',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]],
-  ['tjinitcompress',['tjInitCompress',['../group___turbo_j_p_e_g.html#ga9d63a05fc6d813f4aae06107041a37e8',1,'turbojpeg.h']]],
-  ['tjinitdecompress',['tjInitDecompress',['../group___turbo_j_p_e_g.html#ga52300eac3f3d9ef4bab303bc244f62d3',1,'turbojpeg.h']]],
-  ['tjinittransform',['tjInitTransform',['../group___turbo_j_p_e_g.html#ga928beff6ac248ceadf01089fc6b41957',1,'turbojpeg.h']]],
-  ['tjloadimage',['tjLoadImage',['../group___turbo_j_p_e_g.html#gaffbd83c375e79f5db4b5c5d8ad4466e7',1,'turbojpeg.h']]],
-  ['tjmcuheight',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]],
-  ['tjmcuwidth',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]],
-  ['tjpad',['TJPAD',['../group___turbo_j_p_e_g.html#ga0aba955473315e405295d978f0c16511',1,'turbojpeg.h']]],
-  ['tjpf',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]],
-  ['tjpf_5fabgr',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]],
-  ['tjpf_5fargb',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]],
-  ['tjpf_5fbgr',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]],
-  ['tjpf_5fbgra',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]],
-  ['tjpf_5fbgrx',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]],
-  ['tjpf_5fcmyk',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]],
-  ['tjpf_5fgray',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]],
-  ['tjpf_5frgb',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]],
-  ['tjpf_5frgba',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]],
-  ['tjpf_5frgbx',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]],
-  ['tjpf_5funknown',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]],
-  ['tjpf_5fxbgr',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]],
-  ['tjpf_5fxrgb',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]],
-  ['tjpixelsize',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]],
-  ['tjplaneheight',['tjPlaneHeight',['../group___turbo_j_p_e_g.html#ga1a209696c6a80748f20e134b3c64789f',1,'turbojpeg.h']]],
-  ['tjplanesizeyuv',['tjPlaneSizeYUV',['../group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d',1,'turbojpeg.h']]],
-  ['tjplanewidth',['tjPlaneWidth',['../group___turbo_j_p_e_g.html#ga63fb66bb1e36c74008c4634360becbb1',1,'turbojpeg.h']]],
-  ['tjredoffset',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]],
-  ['tjregion',['tjregion',['../structtjregion.html',1,'']]],
-  ['tjsamp',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]],
-  ['tjsamp_5f411',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]],
-  ['tjsamp_5f420',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]],
-  ['tjsamp_5f422',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]],
-  ['tjsamp_5f440',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]],
-  ['tjsamp_5f444',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]],
-  ['tjsamp_5fgray',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]],
-  ['tjsaveimage',['tjSaveImage',['../group___turbo_j_p_e_g.html#ga6f445b22d8933ae4815b3370a538d879',1,'turbojpeg.h']]],
-  ['tjscaled',['TJSCALED',['../group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df',1,'turbojpeg.h']]],
-  ['tjscalingfactor',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]],
-  ['tjtransform',['tjtransform',['../structtjtransform.html',1,'tjtransform'],['../group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31',1,'tjtransform():&#160;turbojpeg.h'],['../group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25',1,'tjTransform(tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int n, unsigned char **dstBufs, unsigned long *dstSizes, tjtransform *transforms, int flags):&#160;turbojpeg.h']]],
-  ['tjxop',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]],
-  ['tjxop_5fhflip',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]],
-  ['tjxop_5fnone',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]],
-  ['tjxop_5frot180',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]],
-  ['tjxop_5frot270',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]],
-  ['tjxop_5frot90',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]],
-  ['tjxop_5ftranspose',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]],
-  ['tjxop_5ftransverse',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]],
-  ['tjxop_5fvflip',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]],
-  ['tjxopt_5fcopynone',['TJXOPT_COPYNONE',['../group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8',1,'turbojpeg.h']]],
-  ['tjxopt_5fcrop',['TJXOPT_CROP',['../group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2',1,'turbojpeg.h']]],
-  ['tjxopt_5fgray',['TJXOPT_GRAY',['../group___turbo_j_p_e_g.html#ga3acee7b48ade1b99e5588736007c2589',1,'turbojpeg.h']]],
-  ['tjxopt_5fnooutput',['TJXOPT_NOOUTPUT',['../group___turbo_j_p_e_g.html#gafbf992bbf6e006705886333703ffab31',1,'turbojpeg.h']]],
-  ['tjxopt_5fperfect',['TJXOPT_PERFECT',['../group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00',1,'turbojpeg.h']]],
-  ['tjxopt_5fprogressive',['TJXOPT_PROGRESSIVE',['../group___turbo_j_p_e_g.html#gad2371c80674584ecc1a7d75e564cf026',1,'turbojpeg.h']]],
-  ['tjxopt_5ftrim',['TJXOPT_TRIM',['../group___turbo_j_p_e_g.html#ga319826b7eb1583c0595bbe7b95428709',1,'turbojpeg.h']]],
-  ['turbojpeg',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_77.html b/src/third_party/libjpeg-turbo/doc/html/search/all_77.html
deleted file mode 100644
index 55d7142..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_77.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_77.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_77.js b/src/third_party/libjpeg-turbo/doc/html/search/all_77.js
deleted file mode 100644
index 4267002..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_77.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['w',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_78.html b/src/third_party/libjpeg-turbo/doc/html/search/all_78.html
deleted file mode 100644
index 39075d4..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_78.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_78.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_78.js b/src/third_party/libjpeg-turbo/doc/html/search/all_78.js
deleted file mode 100644
index 41a27f2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_78.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['x',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_79.html b/src/third_party/libjpeg-turbo/doc/html/search/all_79.html
deleted file mode 100644
index 033719a..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_79.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="all_79.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/all_79.js b/src/third_party/libjpeg-turbo/doc/html/search/all_79.js
deleted file mode 100644
index 86890a6..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/all_79.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['y',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/classes_74.html b/src/third_party/libjpeg-turbo/doc/html/search/classes_74.html
deleted file mode 100644
index 4b0fdaa..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/classes_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="classes_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/classes_74.js b/src/third_party/libjpeg-turbo/doc/html/search/classes_74.js
deleted file mode 100644
index cd623d2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/classes_74.js
+++ /dev/null
@@ -1,6 +0,0 @@
-var searchData=
-[
-  ['tjregion',['tjregion',['../structtjregion.html',1,'']]],
-  ['tjscalingfactor',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]],
-  ['tjtransform',['tjtransform',['../structtjtransform.html',1,'']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/close.png b/src/third_party/libjpeg-turbo/doc/html/search/close.png
deleted file mode 100644
index 9342d3d..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/close.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/enums_74.html b/src/third_party/libjpeg-turbo/doc/html/search/enums_74.html
deleted file mode 100644
index 9b754ee..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/enums_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="enums_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/enums_74.js b/src/third_party/libjpeg-turbo/doc/html/search/enums_74.js
deleted file mode 100644
index 19c20cf..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/enums_74.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var searchData=
-[
-  ['tjcs',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]],
-  ['tjerr',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]],
-  ['tjpf',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]],
-  ['tjsamp',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]],
-  ['tjxop',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.html b/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.html
deleted file mode 100644
index 0d69a0a..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="enumvalues_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.js b/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.js
deleted file mode 100644
index e683856..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/enumvalues_74.js
+++ /dev/null
@@ -1,37 +0,0 @@
-var searchData=
-[
-  ['tjcs_5fcmyk',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]],
-  ['tjcs_5fgray',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]],
-  ['tjcs_5frgb',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]],
-  ['tjcs_5fycbcr',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]],
-  ['tjcs_5fycck',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]],
-  ['tjerr_5ffatal',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]],
-  ['tjerr_5fwarning',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]],
-  ['tjpf_5fabgr',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]],
-  ['tjpf_5fargb',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]],
-  ['tjpf_5fbgr',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]],
-  ['tjpf_5fbgra',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]],
-  ['tjpf_5fbgrx',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]],
-  ['tjpf_5fcmyk',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]],
-  ['tjpf_5fgray',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]],
-  ['tjpf_5frgb',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]],
-  ['tjpf_5frgba',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]],
-  ['tjpf_5frgbx',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]],
-  ['tjpf_5funknown',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]],
-  ['tjpf_5fxbgr',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]],
-  ['tjpf_5fxrgb',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]],
-  ['tjsamp_5f411',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]],
-  ['tjsamp_5f420',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]],
-  ['tjsamp_5f422',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]],
-  ['tjsamp_5f440',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]],
-  ['tjsamp_5f444',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]],
-  ['tjsamp_5fgray',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]],
-  ['tjxop_5fhflip',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]],
-  ['tjxop_5fnone',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]],
-  ['tjxop_5frot180',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]],
-  ['tjxop_5frot270',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]],
-  ['tjxop_5frot90',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]],
-  ['tjxop_5ftranspose',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]],
-  ['tjxop_5ftransverse',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]],
-  ['tjxop_5fvflip',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/functions_74.html b/src/third_party/libjpeg-turbo/doc/html/search/functions_74.html
deleted file mode 100644
index 1605901..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/functions_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="functions_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/functions_74.js b/src/third_party/libjpeg-turbo/doc/html/search/functions_74.js
deleted file mode 100644
index bd4f34f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/functions_74.js
+++ /dev/null
@@ -1,31 +0,0 @@
-var searchData=
-[
-  ['tjalloc',['tjAlloc',['../group___turbo_j_p_e_g.html#gaec627dd4c5f30b7a775a7aea3bec5d83',1,'turbojpeg.h']]],
-  ['tjbufsize',['tjBufSize',['../group___turbo_j_p_e_g.html#ga67ac12fee79073242cb216e07c9f1f90',1,'turbojpeg.h']]],
-  ['tjbufsizeyuv2',['tjBufSizeYUV2',['../group___turbo_j_p_e_g.html#ga2be2b9969d4df9ecce9b05deed273194',1,'turbojpeg.h']]],
-  ['tjcompress2',['tjCompress2',['../group___turbo_j_p_e_g.html#gafbdce0112fd78fd38efae841443a9bcf',1,'turbojpeg.h']]],
-  ['tjcompressfromyuv',['tjCompressFromYUV',['../group___turbo_j_p_e_g.html#ga7622a459b79aa1007e005b58783f875b',1,'turbojpeg.h']]],
-  ['tjcompressfromyuvplanes',['tjCompressFromYUVPlanes',['../group___turbo_j_p_e_g.html#ga29ec5dfbd2d84b8724e951d6fa0d5d9e',1,'turbojpeg.h']]],
-  ['tjdecodeyuv',['tjDecodeYUV',['../group___turbo_j_p_e_g.html#ga70abbf38f77a26fd6da8813bef96f695',1,'turbojpeg.h']]],
-  ['tjdecodeyuvplanes',['tjDecodeYUVPlanes',['../group___turbo_j_p_e_g.html#ga10e837c07fa9d25770565b237d3898d9',1,'turbojpeg.h']]],
-  ['tjdecompress2',['tjDecompress2',['../group___turbo_j_p_e_g.html#gae9eccef8b682a48f43a9117c231ed013',1,'turbojpeg.h']]],
-  ['tjdecompressheader3',['tjDecompressHeader3',['../group___turbo_j_p_e_g.html#ga0595681096bba7199cc6f3533cb25f77',1,'turbojpeg.h']]],
-  ['tjdecompresstoyuv2',['tjDecompressToYUV2',['../group___turbo_j_p_e_g.html#ga04d1e839ff9a0860dd1475cff78d3364',1,'turbojpeg.h']]],
-  ['tjdecompresstoyuvplanes',['tjDecompressToYUVPlanes',['../group___turbo_j_p_e_g.html#gaa59f901a5258ada5bd0185ad59368540',1,'turbojpeg.h']]],
-  ['tjdestroy',['tjDestroy',['../group___turbo_j_p_e_g.html#ga75f355fa27225ba1a4ee392c852394d2',1,'turbojpeg.h']]],
-  ['tjencodeyuv3',['tjEncodeYUV3',['../group___turbo_j_p_e_g.html#gac519b922cdf446e97d0cdcba513636bf',1,'turbojpeg.h']]],
-  ['tjencodeyuvplanes',['tjEncodeYUVPlanes',['../group___turbo_j_p_e_g.html#gae2d04c72457fe7f4d60cf78ab1b1feb1',1,'turbojpeg.h']]],
-  ['tjfree',['tjFree',['../group___turbo_j_p_e_g.html#gaea863d2da0cdb609563aabdf9196514b',1,'turbojpeg.h']]],
-  ['tjgeterrorcode',['tjGetErrorCode',['../group___turbo_j_p_e_g.html#ga414feeffbf860ebd31c745df203de410',1,'turbojpeg.h']]],
-  ['tjgeterrorstr2',['tjGetErrorStr2',['../group___turbo_j_p_e_g.html#ga1ead8574f9f39fbafc6b497124e7aafa',1,'turbojpeg.h']]],
-  ['tjgetscalingfactors',['tjGetScalingFactors',['../group___turbo_j_p_e_g.html#gac3854476006b10787bd128f7ede48057',1,'turbojpeg.h']]],
-  ['tjinitcompress',['tjInitCompress',['../group___turbo_j_p_e_g.html#ga9d63a05fc6d813f4aae06107041a37e8',1,'turbojpeg.h']]],
-  ['tjinitdecompress',['tjInitDecompress',['../group___turbo_j_p_e_g.html#ga52300eac3f3d9ef4bab303bc244f62d3',1,'turbojpeg.h']]],
-  ['tjinittransform',['tjInitTransform',['../group___turbo_j_p_e_g.html#ga928beff6ac248ceadf01089fc6b41957',1,'turbojpeg.h']]],
-  ['tjloadimage',['tjLoadImage',['../group___turbo_j_p_e_g.html#gaffbd83c375e79f5db4b5c5d8ad4466e7',1,'turbojpeg.h']]],
-  ['tjplaneheight',['tjPlaneHeight',['../group___turbo_j_p_e_g.html#ga1a209696c6a80748f20e134b3c64789f',1,'turbojpeg.h']]],
-  ['tjplanesizeyuv',['tjPlaneSizeYUV',['../group___turbo_j_p_e_g.html#gab4ab7b24f6e797d79abaaa670373961d',1,'turbojpeg.h']]],
-  ['tjplanewidth',['tjPlaneWidth',['../group___turbo_j_p_e_g.html#ga63fb66bb1e36c74008c4634360becbb1',1,'turbojpeg.h']]],
-  ['tjsaveimage',['tjSaveImage',['../group___turbo_j_p_e_g.html#ga6f445b22d8933ae4815b3370a538d879',1,'turbojpeg.h']]],
-  ['tjtransform',['tjTransform',['../group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25',1,'turbojpeg.h']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/groups_74.html b/src/third_party/libjpeg-turbo/doc/html/search/groups_74.html
deleted file mode 100644
index a169560..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/groups_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="groups_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/groups_74.js b/src/third_party/libjpeg-turbo/doc/html/search/groups_74.js
deleted file mode 100644
index 27d4ffb..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/groups_74.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['turbojpeg',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/mag_sel.png b/src/third_party/libjpeg-turbo/doc/html/search/mag_sel.png
deleted file mode 100644
index 81f6040..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/mag_sel.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/nomatches.html b/src/third_party/libjpeg-turbo/doc/html/search/nomatches.html
deleted file mode 100644
index b1ded27..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/nomatches.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="NoMatches">No Matches</div>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/search.css b/src/third_party/libjpeg-turbo/doc/html/search/search.css
deleted file mode 100644
index 5b208ed..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/search.css
+++ /dev/null
@@ -1,271 +0,0 @@
-/*---------------- Search Box */
-
-#FSearchBox {
-    float: left;
-}
-
-#MSearchBox {
-    white-space : nowrap;
-    position: absolute;
-    float: none;
-    display: inline;
-    margin-top: 8px;
-    right: 0px;
-    width: 170px;
-    z-index: 102;
-    background-color: white;
-}
-
-#MSearchBox .left
-{
-    display:block;
-    position:absolute;
-    left:10px;
-    width:20px;
-    height:19px;
-    background:url('search_l.png') no-repeat;
-    background-position:right;
-}
-
-#MSearchSelect {
-    display:block;
-    position:absolute;
-    width:20px;
-    height:19px;
-}
-
-.left #MSearchSelect {
-    left:4px;
-}
-
-.right #MSearchSelect {
-    right:5px;
-}
-
-#MSearchField {
-    display:block;
-    position:absolute;
-    height:19px;
-    background:url('search_m.png') repeat-x;
-    border:none;
-    width:116px;
-    margin-left:20px;
-    padding-left:4px;
-    color: #909090;
-    outline: none;
-    font: 9pt Arial, Verdana, sans-serif;
-}
-
-#FSearchBox #MSearchField {
-    margin-left:15px;
-}
-
-#MSearchBox .right {
-    display:block;
-    position:absolute;
-    right:10px;
-    top:0px;
-    width:20px;
-    height:19px;
-    background:url('search_r.png') no-repeat;
-    background-position:left;
-}
-
-#MSearchClose {
-    display: none;
-    position: absolute;
-    top: 4px;
-    background : none;
-    border: none;
-    margin: 0px 4px 0px 0px;
-    padding: 0px 0px;
-    outline: none;
-}
-
-.left #MSearchClose {
-    left: 6px;
-}
-
-.right #MSearchClose {
-    right: 2px;
-}
-
-.MSearchBoxActive #MSearchField {
-    color: #000000;
-}
-
-/*---------------- Search filter selection */
-
-#MSearchSelectWindow {
-    display: none;
-    position: absolute;
-    left: 0; top: 0;
-    border: 1px solid #90A5CE;
-    background-color: #F9FAFC;
-    z-index: 1;
-    padding-top: 4px;
-    padding-bottom: 4px;
-    -moz-border-radius: 4px;
-    -webkit-border-top-left-radius: 4px;
-    -webkit-border-top-right-radius: 4px;
-    -webkit-border-bottom-left-radius: 4px;
-    -webkit-border-bottom-right-radius: 4px;
-    -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-}
-
-.SelectItem {
-    font: 8pt Arial, Verdana, sans-serif;
-    padding-left:  2px;
-    padding-right: 12px;
-    border: 0px;
-}
-
-span.SelectionMark {
-    margin-right: 4px;
-    font-family: monospace;
-    outline-style: none;
-    text-decoration: none;
-}
-
-a.SelectItem {
-    display: block;
-    outline-style: none;
-    color: #000000; 
-    text-decoration: none;
-    padding-left:   6px;
-    padding-right: 12px;
-}
-
-a.SelectItem:focus,
-a.SelectItem:active {
-    color: #000000; 
-    outline-style: none;
-    text-decoration: none;
-}
-
-a.SelectItem:hover {
-    color: #FFFFFF;
-    background-color: #3D578C;
-    outline-style: none;
-    text-decoration: none;
-    cursor: pointer;
-    display: block;
-}
-
-/*---------------- Search results window */
-
-iframe#MSearchResults {
-    width: 60ex;
-    height: 15em;
-}
-
-#MSearchResultsWindow {
-    display: none;
-    position: absolute;
-    left: 0; top: 0;
-    border: 1px solid #000;
-    background-color: #EEF1F7;
-}
-
-/* ----------------------------------- */
-
-
-#SRIndex {
-    clear:both; 
-    padding-bottom: 15px;
-}
-
-.SREntry {
-    font-size: 10pt;
-    padding-left: 1ex;
-}
-
-.SRPage .SREntry {
-    font-size: 8pt;
-    padding: 1px 5px;
-}
-
-body.SRPage {
-    margin: 5px 2px;
-}
-
-.SRChildren {
-    padding-left: 3ex; padding-bottom: .5em 
-}
-
-.SRPage .SRChildren {
-    display: none;
-}
-
-.SRSymbol {
-    font-weight: bold; 
-    color: #425E97;
-    font-family: Arial, Verdana, sans-serif;
-    text-decoration: none;
-    outline: none;
-}
-
-a.SRScope {
-    display: block;
-    color: #425E97; 
-    font-family: Arial, Verdana, sans-serif;
-    text-decoration: none;
-    outline: none;
-}
-
-a.SRSymbol:focus, a.SRSymbol:active,
-a.SRScope:focus, a.SRScope:active {
-    text-decoration: underline;
-}
-
-span.SRScope {
-    padding-left: 4px;
-}
-
-.SRPage .SRStatus {
-    padding: 2px 5px;
-    font-size: 8pt;
-    font-style: italic;
-}
-
-.SRResult {
-    display: none;
-}
-
-DIV.searchresults {
-    margin-left: 10px;
-    margin-right: 10px;
-}
-
-/*---------------- External search page results */
-
-.searchresult {
-    background-color: #F0F3F8;
-}
-
-.pages b {
-   color: white;
-   padding: 5px 5px 3px 5px;
-   background-image: url("../tab_a.png");
-   background-repeat: repeat-x;
-   text-shadow: 0 1px 1px #000000;
-}
-
-.pages {
-    line-height: 17px;
-    margin-left: 4px;
-    text-decoration: none;
-}
-
-.hl {
-    font-weight: bold;
-}
-
-#searchresults {
-    margin-bottom: 20px;
-}
-
-.searchpages {
-    margin-top: 10px;
-}
-
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/search.js b/src/third_party/libjpeg-turbo/doc/html/search/search.js
deleted file mode 100644
index 409672c..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/search.js
+++ /dev/null
@@ -1,809 +0,0 @@
-// Search script generated by doxygen
-// Copyright (C) 2009 by Dimitri van Heesch.
-
-// The code in this file is loosly based on main.js, part of Natural Docs,
-// which is Copyright (C) 2003-2008 Greg Valure
-// Natural Docs is licensed under the GPL.
-
-var indexSectionsWithContent =
-{
-  0: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100010000011001010011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  1: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  2: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  3: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100010000011001010011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  4: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  5: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  6: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-  7: "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
-};
-
-var indexSectionNames =
-{
-  0: "all",
-  1: "classes",
-  2: "functions",
-  3: "variables",
-  4: "typedefs",
-  5: "enums",
-  6: "enumvalues",
-  7: "groups"
-};
-
-function convertToId(search)
-{
-  var result = '';
-  for (i=0;i<search.length;i++)
-  {
-    var c = search.charAt(i);
-    var cn = c.charCodeAt(0);
-    if (c.match(/[a-z0-9]/))
-    {
-      result+=c;
-    }
-    else if (cn<16) 
-    {
-      result+="_0"+cn.toString(16);
-    }
-    else 
-    {
-      result+="_"+cn.toString(16);
-    }
-  }
-  return result;
-}
-
-function getXPos(item)
-{
-  var x = 0;
-  if (item.offsetWidth)
-  {
-    while (item && item!=document.body)
-    {
-      x   += item.offsetLeft;
-      item = item.offsetParent;
-    }
-  }
-  return x;
-}
-
-function getYPos(item)
-{
-  var y = 0;
-  if (item.offsetWidth)
-  {
-     while (item && item!=document.body)
-     {
-       y   += item.offsetTop;
-       item = item.offsetParent;
-     }
-  }
-  return y;
-}
-
-/* A class handling everything associated with the search panel.
-
-   Parameters:
-   name - The name of the global variable that will be 
-          storing this instance.  Is needed to be able to set timeouts.
-   resultPath - path to use for external files
-*/
-function SearchBox(name, resultsPath, inFrame, label)
-{
-  if (!name || !resultsPath) {  alert("Missing parameters to SearchBox."); }
-   
-  // ---------- Instance variables
-  this.name                  = name;
-  this.resultsPath           = resultsPath;
-  this.keyTimeout            = 0;
-  this.keyTimeoutLength      = 500;
-  this.closeSelectionTimeout = 300;
-  this.lastSearchValue       = "";
-  this.lastResultsPage       = "";
-  this.hideTimeout           = 0;
-  this.searchIndex           = 0;
-  this.searchActive          = false;
-  this.insideFrame           = inFrame;
-  this.searchLabel           = label;
-
-  // ----------- DOM Elements
-
-  this.DOMSearchField = function()
-  {  return document.getElementById("MSearchField");  }
-
-  this.DOMSearchSelect = function()
-  {  return document.getElementById("MSearchSelect");  }
-
-  this.DOMSearchSelectWindow = function()
-  {  return document.getElementById("MSearchSelectWindow");  }
-
-  this.DOMPopupSearchResults = function()
-  {  return document.getElementById("MSearchResults");  }
-
-  this.DOMPopupSearchResultsWindow = function()
-  {  return document.getElementById("MSearchResultsWindow");  }
-
-  this.DOMSearchClose = function()
-  {  return document.getElementById("MSearchClose"); }
-
-  this.DOMSearchBox = function()
-  {  return document.getElementById("MSearchBox");  }
-
-  // ------------ Event Handlers
-
-  // Called when focus is added or removed from the search field.
-  this.OnSearchFieldFocus = function(isActive)
-  {
-    this.Activate(isActive);
-  }
-
-  this.OnSearchSelectShow = function()
-  {
-    var searchSelectWindow = this.DOMSearchSelectWindow();
-    var searchField        = this.DOMSearchSelect();
-
-    if (this.insideFrame)
-    {
-      var left = getXPos(searchField);
-      var top  = getYPos(searchField);
-      left += searchField.offsetWidth + 6;
-      top += searchField.offsetHeight;
-
-      // show search selection popup
-      searchSelectWindow.style.display='block';
-      left -= searchSelectWindow.offsetWidth;
-      searchSelectWindow.style.left =  left + 'px';
-      searchSelectWindow.style.top  =  top  + 'px';
-    }
-    else
-    {
-      var left = getXPos(searchField);
-      var top  = getYPos(searchField);
-      top += searchField.offsetHeight;
-
-      // show search selection popup
-      searchSelectWindow.style.display='block';
-      searchSelectWindow.style.left =  left + 'px';
-      searchSelectWindow.style.top  =  top  + 'px';
-    }
-
-    // stop selection hide timer
-    if (this.hideTimeout) 
-    {
-      clearTimeout(this.hideTimeout);
-      this.hideTimeout=0;
-    }
-    return false; // to avoid "image drag" default event
-  }
-
-  this.OnSearchSelectHide = function()
-  {
-    this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
-                                  this.closeSelectionTimeout);
-  }
-
-  // Called when the content of the search field is changed.
-  this.OnSearchFieldChange = function(evt)
-  {
-    if (this.keyTimeout) // kill running timer
-    {
-      clearTimeout(this.keyTimeout);
-      this.keyTimeout = 0;
-    }
-
-    var e  = (evt) ? evt : window.event; // for IE
-    if (e.keyCode==40 || e.keyCode==13)
-    {
-      if (e.shiftKey==1)
-      {
-        this.OnSearchSelectShow();
-        var win=this.DOMSearchSelectWindow(); 
-        for (i=0;i<win.childNodes.length;i++)
-        {
-          var child = win.childNodes[i]; // get span within a
-          if (child.className=='SelectItem')
-          {
-            child.focus();
-            return;
-          }
-        }
-        return;
-      }
-      else if (window.frames.MSearchResults.searchResults)
-      {
-        var elem = window.frames.MSearchResults.searchResults.NavNext(0);
-        if (elem) elem.focus();
-      }
-    }
-    else if (e.keyCode==27) // Escape out of the search field
-    {
-      this.DOMSearchField().blur();
-      this.DOMPopupSearchResultsWindow().style.display = 'none';
-      this.DOMSearchClose().style.display = 'none';
-      this.lastSearchValue = '';
-      this.Activate(false);
-      return;
-    }
-
-    // strip whitespaces
-    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
-
-    if (searchValue != this.lastSearchValue) // search value has changed
-    {
-      if (searchValue != "") // non-empty search
-      {
-        // set timer for search update
-        this.keyTimeout = setTimeout(this.name + '.Search()',
-                                     this.keyTimeoutLength);
-      }
-      else // empty search field
-      {
-        this.DOMPopupSearchResultsWindow().style.display = 'none';
-        this.DOMSearchClose().style.display = 'none';
-        this.lastSearchValue = '';
-      }
-    }
-  }
-
-  this.SelectItemCount = function(id)
-  {
-    var count=0;
-    var win=this.DOMSearchSelectWindow(); 
-    for (i=0;i<win.childNodes.length;i++)
-    {
-      var child = win.childNodes[i]; // get span within a
-      if (child.className=='SelectItem')
-      {
-        count++;
-      }
-    }
-    return count;
-  }
-
-  this.SelectItemSet = function(id)
-  {
-    var i,j=0;
-    var win=this.DOMSearchSelectWindow(); 
-    for (i=0;i<win.childNodes.length;i++)
-    {
-      var child = win.childNodes[i]; // get span within a
-      if (child.className=='SelectItem')
-      {
-        var node = child.firstChild;
-        if (j==id)
-        {
-          node.innerHTML='&#8226;';
-        }
-        else
-        {
-          node.innerHTML='&#160;';
-        }
-        j++;
-      }
-    }
-  }
-
-  // Called when an search filter selection is made.
-  // set item with index id as the active item
-  this.OnSelectItem = function(id)
-  {
-    this.searchIndex = id;
-    this.SelectItemSet(id);
-    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
-    if (searchValue!="" && this.searchActive) // something was found -> do a search
-    {
-      this.Search();
-    }
-  }
-
-  this.OnSearchSelectKey = function(evt)
-  {
-    var e = (evt) ? evt : window.event; // for IE
-    if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
-    {
-      this.searchIndex++;
-      this.OnSelectItem(this.searchIndex);
-    }
-    else if (e.keyCode==38 && this.searchIndex>0) // Up
-    {
-      this.searchIndex--;
-      this.OnSelectItem(this.searchIndex);
-    }
-    else if (e.keyCode==13 || e.keyCode==27)
-    {
-      this.OnSelectItem(this.searchIndex);
-      this.CloseSelectionWindow();
-      this.DOMSearchField().focus();
-    }
-    return false;
-  }
-
-  // --------- Actions
-
-  // Closes the results window.
-  this.CloseResultsWindow = function()
-  {
-    this.DOMPopupSearchResultsWindow().style.display = 'none';
-    this.DOMSearchClose().style.display = 'none';
-    this.Activate(false);
-  }
-
-  this.CloseSelectionWindow = function()
-  {
-    this.DOMSearchSelectWindow().style.display = 'none';
-  }
-
-  // Performs a search.
-  this.Search = function()
-  {
-    this.keyTimeout = 0;
-
-    // strip leading whitespace
-    var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
-
-    var code = searchValue.toLowerCase().charCodeAt(0);
-    var hexCode;
-    if (code<16) 
-    {
-      hexCode="0"+code.toString(16);
-    }
-    else 
-    {
-      hexCode=code.toString(16);
-    }
-
-    var resultsPage;
-    var resultsPageWithSearch;
-    var hasResultsPage;
-
-    if (indexSectionsWithContent[this.searchIndex].charAt(code) == '1')
-    {
-       resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
-       resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
-       hasResultsPage = true;
-    }
-    else // nothing available for this search term
-    {
-       resultsPage = this.resultsPath + '/nomatches.html';
-       resultsPageWithSearch = resultsPage;
-       hasResultsPage = false;
-    }
-
-    window.frames.MSearchResults.location = resultsPageWithSearch;  
-    var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
-
-    if (domPopupSearchResultsWindow.style.display!='block')
-    {
-       var domSearchBox = this.DOMSearchBox();
-       this.DOMSearchClose().style.display = 'inline';
-       if (this.insideFrame)
-       {
-         var domPopupSearchResults = this.DOMPopupSearchResults();
-         domPopupSearchResultsWindow.style.position = 'relative';
-         domPopupSearchResultsWindow.style.display  = 'block';
-         var width = document.body.clientWidth - 8; // the -8 is for IE :-(
-         domPopupSearchResultsWindow.style.width    = width + 'px';
-         domPopupSearchResults.style.width          = width + 'px';
-       }
-       else
-       {
-         var domPopupSearchResults = this.DOMPopupSearchResults();
-         var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
-         var top  = getYPos(domSearchBox) + 20;  // domSearchBox.offsetHeight + 1;
-         domPopupSearchResultsWindow.style.display = 'block';
-         left -= domPopupSearchResults.offsetWidth;
-         domPopupSearchResultsWindow.style.top     = top  + 'px';
-         domPopupSearchResultsWindow.style.left    = left + 'px';
-       }
-    }
-
-    this.lastSearchValue = searchValue;
-    this.lastResultsPage = resultsPage;
-  }
-
-  // -------- Activation Functions
-
-  // Activates or deactivates the search panel, resetting things to 
-  // their default values if necessary. 
-  this.Activate = function(isActive)
-  {
-    if (isActive || // open it
-        this.DOMPopupSearchResultsWindow().style.display == 'block' 
-       )
-    {
-      this.DOMSearchBox().className = 'MSearchBoxActive';
-
-      var searchField = this.DOMSearchField();
-
-      if (searchField.value == this.searchLabel) // clear "Search" term upon entry
-      {  
-        searchField.value = '';  
-        this.searchActive = true;
-      }
-    }
-    else if (!isActive) // directly remove the panel
-    {
-      this.DOMSearchBox().className = 'MSearchBoxInactive';
-      this.DOMSearchField().value   = this.searchLabel;
-      this.searchActive             = false;
-      this.lastSearchValue          = ''
-      this.lastResultsPage          = '';
-    }
-  }
-}
-
-// -----------------------------------------------------------------------
-
-// The class that handles everything on the search results page.
-function SearchResults(name)
-{
-    // The number of matches from the last run of <Search()>.
-    this.lastMatchCount = 0;
-    this.lastKey = 0;
-    this.repeatOn = false;
-
-    // Toggles the visibility of the passed element ID.
-    this.FindChildElement = function(id)
-    {
-      var parentElement = document.getElementById(id);
-      var element = parentElement.firstChild;
-
-      while (element && element!=parentElement)
-      {
-        if (element.nodeName == 'DIV' && element.className == 'SRChildren')
-        {
-          return element;
-        }
-
-        if (element.nodeName == 'DIV' && element.hasChildNodes())
-        {  
-           element = element.firstChild;  
-        }
-        else if (element.nextSibling)
-        {  
-           element = element.nextSibling;  
-        }
-        else
-        {
-          do
-          {
-            element = element.parentNode;
-          }
-          while (element && element!=parentElement && !element.nextSibling);
-
-          if (element && element!=parentElement)
-          {  
-            element = element.nextSibling;  
-          }
-        }
-      }
-    }
-
-    this.Toggle = function(id)
-    {
-      var element = this.FindChildElement(id);
-      if (element)
-      {
-        if (element.style.display == 'block')
-        {
-          element.style.display = 'none';
-        }
-        else
-        {
-          element.style.display = 'block';
-        }
-      }
-    }
-
-    // Searches for the passed string.  If there is no parameter,
-    // it takes it from the URL query.
-    //
-    // Always returns true, since other documents may try to call it
-    // and that may or may not be possible.
-    this.Search = function(search)
-    {
-      if (!search) // get search word from URL
-      {
-        search = window.location.search;
-        search = search.substring(1);  // Remove the leading '?'
-        search = unescape(search);
-      }
-
-      search = search.replace(/^ +/, ""); // strip leading spaces
-      search = search.replace(/ +$/, ""); // strip trailing spaces
-      search = search.toLowerCase();
-      search = convertToId(search);
-
-      var resultRows = document.getElementsByTagName("div");
-      var matches = 0;
-
-      var i = 0;
-      while (i < resultRows.length)
-      {
-        var row = resultRows.item(i);
-        if (row.className == "SRResult")
-        {
-          var rowMatchName = row.id.toLowerCase();
-          rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
-
-          if (search.length<=rowMatchName.length && 
-             rowMatchName.substr(0, search.length)==search)
-          {
-            row.style.display = 'block';
-            matches++;
-          }
-          else
-          {
-            row.style.display = 'none';
-          }
-        }
-        i++;
-      }
-      document.getElementById("Searching").style.display='none';
-      if (matches == 0) // no results
-      {
-        document.getElementById("NoMatches").style.display='block';
-      }
-      else // at least one result
-      {
-        document.getElementById("NoMatches").style.display='none';
-      }
-      this.lastMatchCount = matches;
-      return true;
-    }
-
-    // return the first item with index index or higher that is visible
-    this.NavNext = function(index)
-    {
-      var focusItem;
-      while (1)
-      {
-        var focusName = 'Item'+index;
-        focusItem = document.getElementById(focusName);
-        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
-        {
-          break;
-        }
-        else if (!focusItem) // last element
-        {
-          break;
-        }
-        focusItem=null;
-        index++;
-      }
-      return focusItem;
-    }
-
-    this.NavPrev = function(index)
-    {
-      var focusItem;
-      while (1)
-      {
-        var focusName = 'Item'+index;
-        focusItem = document.getElementById(focusName);
-        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
-        {
-          break;
-        }
-        else if (!focusItem) // last element
-        {
-          break;
-        }
-        focusItem=null;
-        index--;
-      }
-      return focusItem;
-    }
-
-    this.ProcessKeys = function(e)
-    {
-      if (e.type == "keydown") 
-      {
-        this.repeatOn = false;
-        this.lastKey = e.keyCode;
-      }
-      else if (e.type == "keypress")
-      {
-        if (!this.repeatOn)
-        {
-          if (this.lastKey) this.repeatOn = true;
-          return false; // ignore first keypress after keydown
-        }
-      }
-      else if (e.type == "keyup")
-      {
-        this.lastKey = 0;
-        this.repeatOn = false;
-      }
-      return this.lastKey!=0;
-    }
-
-    this.Nav = function(evt,itemIndex) 
-    {
-      var e  = (evt) ? evt : window.event; // for IE
-      if (e.keyCode==13) return true;
-      if (!this.ProcessKeys(e)) return false;
-
-      if (this.lastKey==38) // Up
-      {
-        var newIndex = itemIndex-1;
-        var focusItem = this.NavPrev(newIndex);
-        if (focusItem)
-        {
-          var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
-          if (child && child.style.display == 'block') // children visible
-          { 
-            var n=0;
-            var tmpElem;
-            while (1) // search for last child
-            {
-              tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
-              if (tmpElem)
-              {
-                focusItem = tmpElem;
-              }
-              else // found it!
-              {
-                break;
-              }
-              n++;
-            }
-          }
-        }
-        if (focusItem)
-        {
-          focusItem.focus();
-        }
-        else // return focus to search field
-        {
-           parent.document.getElementById("MSearchField").focus();
-        }
-      }
-      else if (this.lastKey==40) // Down
-      {
-        var newIndex = itemIndex+1;
-        var focusItem;
-        var item = document.getElementById('Item'+itemIndex);
-        var elem = this.FindChildElement(item.parentNode.parentNode.id);
-        if (elem && elem.style.display == 'block') // children visible
-        {
-          focusItem = document.getElementById('Item'+itemIndex+'_c0');
-        }
-        if (!focusItem) focusItem = this.NavNext(newIndex);
-        if (focusItem)  focusItem.focus();
-      }
-      else if (this.lastKey==39) // Right
-      {
-        var item = document.getElementById('Item'+itemIndex);
-        var elem = this.FindChildElement(item.parentNode.parentNode.id);
-        if (elem) elem.style.display = 'block';
-      }
-      else if (this.lastKey==37) // Left
-      {
-        var item = document.getElementById('Item'+itemIndex);
-        var elem = this.FindChildElement(item.parentNode.parentNode.id);
-        if (elem) elem.style.display = 'none';
-      }
-      else if (this.lastKey==27) // Escape
-      {
-        parent.searchBox.CloseResultsWindow();
-        parent.document.getElementById("MSearchField").focus();
-      }
-      else if (this.lastKey==13) // Enter
-      {
-        return true;
-      }
-      return false;
-    }
-
-    this.NavChild = function(evt,itemIndex,childIndex)
-    {
-      var e  = (evt) ? evt : window.event; // for IE
-      if (e.keyCode==13) return true;
-      if (!this.ProcessKeys(e)) return false;
-
-      if (this.lastKey==38) // Up
-      {
-        if (childIndex>0)
-        {
-          var newIndex = childIndex-1;
-          document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
-        }
-        else // already at first child, jump to parent
-        {
-          document.getElementById('Item'+itemIndex).focus();
-        }
-      }
-      else if (this.lastKey==40) // Down
-      {
-        var newIndex = childIndex+1;
-        var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
-        if (!elem) // last child, jump to parent next parent
-        {
-          elem = this.NavNext(itemIndex+1);
-        }
-        if (elem)
-        {
-          elem.focus();
-        } 
-      }
-      else if (this.lastKey==27) // Escape
-      {
-        parent.searchBox.CloseResultsWindow();
-        parent.document.getElementById("MSearchField").focus();
-      }
-      else if (this.lastKey==13) // Enter
-      {
-        return true;
-      }
-      return false;
-    }
-}
-
-function setKeyActions(elem,action)
-{
-  elem.setAttribute('onkeydown',action);
-  elem.setAttribute('onkeypress',action);
-  elem.setAttribute('onkeyup',action);
-}
-
-function setClassAttr(elem,attr)
-{
-  elem.setAttribute('class',attr);
-  elem.setAttribute('className',attr);
-}
-
-function createResults()
-{
-  var results = document.getElementById("SRResults");
-  for (var e=0; e<searchData.length; e++)
-  {
-    var id = searchData[e][0];
-    var srResult = document.createElement('div');
-    srResult.setAttribute('id','SR_'+id);
-    setClassAttr(srResult,'SRResult');
-    var srEntry = document.createElement('div');
-    setClassAttr(srEntry,'SREntry');
-    var srLink = document.createElement('a');
-    srLink.setAttribute('id','Item'+e);
-    setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
-    setClassAttr(srLink,'SRSymbol');
-    srLink.innerHTML = searchData[e][1][0];
-    srEntry.appendChild(srLink);
-    if (searchData[e][1].length==2) // single result
-    {
-      srLink.setAttribute('href',searchData[e][1][1][0]);
-      if (searchData[e][1][1][1])
-      {
-       srLink.setAttribute('target','_parent');
-      }
-      var srScope = document.createElement('span');
-      setClassAttr(srScope,'SRScope');
-      srScope.innerHTML = searchData[e][1][1][2];
-      srEntry.appendChild(srScope);
-    }
-    else // multiple results
-    {
-      srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
-      var srChildren = document.createElement('div');
-      setClassAttr(srChildren,'SRChildren');
-      for (var c=0; c<searchData[e][1].length-1; c++)
-      {
-        var srChild = document.createElement('a');
-        srChild.setAttribute('id','Item'+e+'_c'+c);
-        setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
-        setClassAttr(srChild,'SRScope');
-        srChild.setAttribute('href',searchData[e][1][c+1][0]);
-        if (searchData[e][1][c+1][1])
-        {
-         srChild.setAttribute('target','_parent');
-        }
-        srChild.innerHTML = searchData[e][1][c+1][2];
-        srChildren.appendChild(srChild);
-      }
-      srEntry.appendChild(srChildren);
-    }
-    srResult.appendChild(srEntry);
-    results.appendChild(srResult);
-  }
-}
-
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/search_l.png b/src/third_party/libjpeg-turbo/doc/html/search/search_l.png
deleted file mode 100644
index c872f4d..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/search_l.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/search_m.png b/src/third_party/libjpeg-turbo/doc/html/search/search_m.png
deleted file mode 100644
index b429a16..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/search_m.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/search_r.png b/src/third_party/libjpeg-turbo/doc/html/search/search_r.png
deleted file mode 100644
index 97ee8b4..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/search_r.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.html b/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.html
deleted file mode 100644
index b2f6d2a..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="typedefs_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.js b/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.js
deleted file mode 100644
index 85b00f5..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/typedefs_74.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var searchData=
-[
-  ['tjhandle',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]],
-  ['tjtransform',['tjtransform',['../group___turbo_j_p_e_g.html#gaa29f3189c41be12ec5dee7caec318a31',1,'turbojpeg.h']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_63.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_63.html
deleted file mode 100644
index 422085c..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_63.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_63.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_63.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_63.js
deleted file mode 100644
index 7b058da..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_63.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['customfilter',['customFilter',['../structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_64.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_64.html
deleted file mode 100644
index df4414b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_64.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_64.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_64.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_64.js
deleted file mode 100644
index e19a050..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_64.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var searchData=
-[
-  ['data',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]],
-  ['denom',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_68.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_68.html
deleted file mode 100644
index 2f0a862..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_68.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_68.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_68.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_68.js
deleted file mode 100644
index 7b17e97..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_68.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['h',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.html
deleted file mode 100644
index 2eb4def..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_6e.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.js
deleted file mode 100644
index 83faa13..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_6e.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['num',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.html
deleted file mode 100644
index f06e2e0..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_6f.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.js
deleted file mode 100644
index 1cca832..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_6f.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var searchData=
-[
-  ['op',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]],
-  ['options',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_72.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_72.html
deleted file mode 100644
index 8a4ee7b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_72.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_72.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_72.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_72.js
deleted file mode 100644
index 01cde35..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_72.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['r',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_74.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_74.html
deleted file mode 100644
index 1665fb8..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_74.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_74.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_74.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_74.js
deleted file mode 100644
index 2d20942..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_74.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var searchData=
-[
-  ['tjalphaoffset',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]],
-  ['tjblueoffset',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]],
-  ['tjgreenoffset',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]],
-  ['tjmcuheight',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]],
-  ['tjmcuwidth',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]],
-  ['tjpixelsize',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]],
-  ['tjredoffset',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_77.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_77.html
deleted file mode 100644
index 434c6df..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_77.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_77.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_77.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_77.js
deleted file mode 100644
index 4267002..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_77.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['w',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_78.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_78.html
deleted file mode 100644
index 602e879..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_78.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_78.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_78.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_78.js
deleted file mode 100644
index 41a27f2..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_78.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['x',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_79.html b/src/third_party/libjpeg-turbo/doc/html/search/variables_79.html
deleted file mode 100644
index 17faef9..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_79.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html><head><title></title>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta name="generator" content="Doxygen 1.8.3.1">
-<link rel="stylesheet" type="text/css" href="search.css"/>
-<script type="text/javascript" src="variables_79.js"></script>
-<script type="text/javascript" src="search.js"></script>
-</head>
-<body class="SRPage">
-<div id="SRIndex">
-<div class="SRStatus" id="Loading">Loading...</div>
-<div id="SRResults"></div>
-<script type="text/javascript"><!--
-createResults();
---></script>
-<div class="SRStatus" id="Searching">Searching...</div>
-<div class="SRStatus" id="NoMatches">No Matches</div>
-<script type="text/javascript"><!--
-document.getElementById("Loading").style.display="none";
-document.getElementById("NoMatches").style.display="none";
-var searchResults = new SearchResults("searchResults");
-searchResults.Search();
---></script>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/search/variables_79.js b/src/third_party/libjpeg-turbo/doc/html/search/variables_79.js
deleted file mode 100644
index 86890a6..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/search/variables_79.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var searchData=
-[
-  ['y',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]]
-];
diff --git a/src/third_party/libjpeg-turbo/doc/html/structtjregion.html b/src/third_party/libjpeg-turbo/doc/html/structtjregion.html
deleted file mode 100644
index 50a9adb..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/structtjregion.html
+++ /dev/null
@@ -1,186 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: tjregion Struct Reference</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-</div><!-- top -->
-<div class="header">
-  <div class="summary">
-<a href="#pub-attribs">Data Fields</a>  </div>
-  <div class="headertitle">
-<div class="title">tjregion Struct Reference<div class="ingroups"><a class="el" href="group___turbo_j_p_e_g.html">TurboJPEG</a></div></div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p>Cropping region.  
- <a href="structtjregion.html#details">More...</a></p>
-
-<p><code>#include &lt;turbojpeg.h&gt;</code></p>
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
-Data Fields</h2></td></tr>
-<tr class="memitem:a4b6a37a93997091b26a75831fa291ad9"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjregion.html#a4b6a37a93997091b26a75831fa291ad9">x</a></td></tr>
-<tr class="memdesc:a4b6a37a93997091b26a75831fa291ad9"><td class="mdescLeft">&#160;</td><td class="mdescRight">The left boundary of the cropping region.  <a href="#a4b6a37a93997091b26a75831fa291ad9">More...</a><br/></td></tr>
-<tr class="separator:a4b6a37a93997091b26a75831fa291ad9"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a7b3e0c24cfe87acc80e334cafdcf22c2"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2">y</a></td></tr>
-<tr class="memdesc:a7b3e0c24cfe87acc80e334cafdcf22c2"><td class="mdescLeft">&#160;</td><td class="mdescRight">The upper boundary of the cropping region.  <a href="#a7b3e0c24cfe87acc80e334cafdcf22c2">More...</a><br/></td></tr>
-<tr class="separator:a7b3e0c24cfe87acc80e334cafdcf22c2"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ab6eb73ceef584fc23c8c8097926dce42"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42">w</a></td></tr>
-<tr class="memdesc:ab6eb73ceef584fc23c8c8097926dce42"><td class="mdescLeft">&#160;</td><td class="mdescRight">The width of the cropping region.  <a href="#ab6eb73ceef584fc23c8c8097926dce42">More...</a><br/></td></tr>
-<tr class="separator:ab6eb73ceef584fc23c8c8097926dce42"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:aecefc45a26f4d8b60dd4d825c1710115"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115">h</a></td></tr>
-<tr class="memdesc:aecefc45a26f4d8b60dd4d825c1710115"><td class="mdescLeft">&#160;</td><td class="mdescRight">The height of the cropping region.  <a href="#aecefc45a26f4d8b60dd4d825c1710115">More...</a><br/></td></tr>
-<tr class="separator:aecefc45a26f4d8b60dd4d825c1710115"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<div class="textblock"><p>Cropping region. </p>
-</div><h2 class="groupheader">Field Documentation</h2>
-<a class="anchor" id="aecefc45a26f4d8b60dd4d825c1710115"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjregion::h</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The height of the cropping region. </p>
-<p>Setting this to 0 is the equivalent of setting it to the height of the source JPEG image - y. </p>
-
-</div>
-</div>
-<a class="anchor" id="ab6eb73ceef584fc23c8c8097926dce42"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjregion::w</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The width of the cropping region. </p>
-<p>Setting this to 0 is the equivalent of setting it to the width of the source JPEG image - x. </p>
-
-</div>
-</div>
-<a class="anchor" id="a4b6a37a93997091b26a75831fa291ad9"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjregion::x</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The left boundary of the cropping region. </p>
-<p>This must be evenly divisible by the MCU block width (see <a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>.) </p>
-
-</div>
-</div>
-<a class="anchor" id="a7b3e0c24cfe87acc80e334cafdcf22c2"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjregion::y</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The upper boundary of the cropping region. </p>
-<p>This must be evenly divisible by the MCU block height (see <a class="el" href="group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf" title="MCU block height (in pixels) for a given level of chrominance subsampling.">tjMCUHeight</a>.) </p>
-
-</div>
-</div>
-<hr/>The documentation for this struct was generated from the following file:<ul>
-<li>turbojpeg.h</li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/structtjscalingfactor.html b/src/third_party/libjpeg-turbo/doc/html/structtjscalingfactor.html
deleted file mode 100644
index d7fa67b..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/structtjscalingfactor.html
+++ /dev/null
@@ -1,148 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: tjscalingfactor Struct Reference</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-</div><!-- top -->
-<div class="header">
-  <div class="summary">
-<a href="#pub-attribs">Data Fields</a>  </div>
-  <div class="headertitle">
-<div class="title">tjscalingfactor Struct Reference<div class="ingroups"><a class="el" href="group___turbo_j_p_e_g.html">TurboJPEG</a></div></div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p>Scaling factor.  
- <a href="structtjscalingfactor.html#details">More...</a></p>
-
-<p><code>#include &lt;turbojpeg.h&gt;</code></p>
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
-Data Fields</h2></td></tr>
-<tr class="memitem:a9b011e57f981ee23083e2c1aa5e640ec"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec">num</a></td></tr>
-<tr class="memdesc:a9b011e57f981ee23083e2c1aa5e640ec"><td class="mdescLeft">&#160;</td><td class="mdescRight">Numerator.  <a href="#a9b011e57f981ee23083e2c1aa5e640ec">More...</a><br/></td></tr>
-<tr class="separator:a9b011e57f981ee23083e2c1aa5e640ec"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:aefbcdf3e9e62274b2d312c695f133ce3"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3">denom</a></td></tr>
-<tr class="memdesc:aefbcdf3e9e62274b2d312c695f133ce3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Denominator.  <a href="#aefbcdf3e9e62274b2d312c695f133ce3">More...</a><br/></td></tr>
-<tr class="separator:aefbcdf3e9e62274b2d312c695f133ce3"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<div class="textblock"><p>Scaling factor. </p>
-</div><h2 class="groupheader">Field Documentation</h2>
-<a class="anchor" id="aefbcdf3e9e62274b2d312c695f133ce3"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjscalingfactor::denom</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Denominator. </p>
-
-</div>
-</div>
-<a class="anchor" id="a9b011e57f981ee23083e2c1aa5e640ec"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjscalingfactor::num</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Numerator. </p>
-
-</div>
-</div>
-<hr/>The documentation for this struct was generated from the following file:<ul>
-<li>turbojpeg.h</li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/structtjtransform.html b/src/third_party/libjpeg-turbo/doc/html/structtjtransform.html
deleted file mode 100644
index fcf72ee..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/structtjtransform.html
+++ /dev/null
@@ -1,212 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
-<meta http-equiv="X-UA-Compatible" content="IE=9"/>
-<meta name="generator" content="Doxygen 1.8.3.1"/>
-<title>TurboJPEG: tjtransform Struct Reference</title>
-<link href="tabs.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="jquery.js"></script>
-<script type="text/javascript" src="dynsections.js"></script>
-<link href="search/search.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="search/search.js"></script>
-<script type="text/javascript">
-  $(document).ready(function() { searchBox.OnSelectItem(0); });
-</script>
-<link href="doxygen.css" rel="stylesheet" type="text/css" />
-<link href="doxygen-extra.css" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
-<div id="titlearea">
-<table cellspacing="0" cellpadding="0">
- <tbody>
- <tr style="height: 56px;">
-  <td style="padding-left: 0.5em;">
-   <div id="projectname">TurboJPEG
-   &#160;<span id="projectnumber">2.0</span>
-   </div>
-  </td>
- </tr>
- </tbody>
-</table>
-</div>
-<!-- end header part -->
-<!-- Generated by Doxygen 1.8.3.1 -->
-<script type="text/javascript">
-var searchBox = new SearchBox("searchBox", "search",false,'Search');
-</script>
-  <div id="navrow1" class="tabs">
-    <ul class="tablist">
-      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
-      <li><a href="modules.html"><span>Modules</span></a></li>
-      <li class="current"><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li>
-        <div id="MSearchBox" class="MSearchBoxInactive">
-        <span class="left">
-          <img id="MSearchSelect" src="search/mag_sel.png"
-               onmouseover="return searchBox.OnSearchSelectShow()"
-               onmouseout="return searchBox.OnSearchSelectHide()"
-               alt=""/>
-          <input type="text" id="MSearchField" value="Search" accesskey="S"
-               onfocus="searchBox.OnSearchFieldFocus(true)" 
-               onblur="searchBox.OnSearchFieldFocus(false)" 
-               onkeyup="searchBox.OnSearchFieldChange(event)"/>
-          </span><span class="right">
-            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
-          </span>
-        </div>
-      </li>
-    </ul>
-  </div>
-  <div id="navrow2" class="tabs2">
-    <ul class="tablist">
-      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
-      <li><a href="classes.html"><span>Data&#160;Structure&#160;Index</span></a></li>
-      <li><a href="functions.html"><span>Data&#160;Fields</span></a></li>
-    </ul>
-  </div>
-<!-- window showing the filter options -->
-<div id="MSearchSelectWindow"
-     onmouseover="return searchBox.OnSearchSelectShow()"
-     onmouseout="return searchBox.OnSearchSelectHide()"
-     onkeydown="return searchBox.OnSearchSelectKey(event)">
-<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Data Structures</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Groups</a></div>
-
-<!-- iframe showing the search results (closed by default) -->
-<div id="MSearchResultsWindow">
-<iframe src="javascript:void(0)" frameborder="0" 
-        name="MSearchResults" id="MSearchResults">
-</iframe>
-</div>
-
-</div><!-- top -->
-<div class="header">
-  <div class="summary">
-<a href="#pub-attribs">Data Fields</a>  </div>
-  <div class="headertitle">
-<div class="title">tjtransform Struct Reference<div class="ingroups"><a class="el" href="group___turbo_j_p_e_g.html">TurboJPEG</a></div></div>  </div>
-</div><!--header-->
-<div class="contents">
-
-<p>Lossless transform.  
- <a href="structtjtransform.html#details">More...</a></p>
-
-<p><code>#include &lt;turbojpeg.h&gt;</code></p>
-<table class="memberdecls">
-<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
-Data Fields</h2></td></tr>
-<tr class="memitem:ac324e5e442abec8a961e5bf219db12cf"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structtjregion.html">tjregion</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf">r</a></td></tr>
-<tr class="memdesc:ac324e5e442abec8a961e5bf219db12cf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Cropping region.  <a href="#ac324e5e442abec8a961e5bf219db12cf">More...</a><br/></td></tr>
-<tr class="separator:ac324e5e442abec8a961e5bf219db12cf"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a2525aab4ba6978a1c273f74fef50e498"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498">op</a></td></tr>
-<tr class="memdesc:a2525aab4ba6978a1c273f74fef50e498"><td class="mdescLeft">&#160;</td><td class="mdescRight">One of the <a class="el" href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">transform operations</a>.  <a href="#a2525aab4ba6978a1c273f74fef50e498">More...</a><br/></td></tr>
-<tr class="separator:a2525aab4ba6978a1c273f74fef50e498"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:ac0e74655baa4402209a21e1ae481c8f6"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6">options</a></td></tr>
-<tr class="memdesc:ac0e74655baa4402209a21e1ae481c8f6"><td class="mdescLeft">&#160;</td><td class="mdescRight">The bitwise OR of one of more of the <a class="el" href="group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2">transform options</a>.  <a href="#ac0e74655baa4402209a21e1ae481c8f6">More...</a><br/></td></tr>
-<tr class="separator:ac0e74655baa4402209a21e1ae481c8f6"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a688fe8f1a8ecc12a538d9e561cf338e3"><td class="memItemLeft" align="right" valign="top">void *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3">data</a></td></tr>
-<tr class="memdesc:a688fe8f1a8ecc12a538d9e561cf338e3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Arbitrary data that can be accessed within the body of the callback function.  <a href="#a688fe8f1a8ecc12a538d9e561cf338e3">More...</a><br/></td></tr>
-<tr class="separator:a688fe8f1a8ecc12a538d9e561cf338e3"><td class="memSeparator" colspan="2">&#160;</td></tr>
-<tr class="memitem:a43ee1bcdd2a8d7249a756774f78793c1"><td class="memItemLeft" align="right" valign="top">int(*&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structtjtransform.html#a43ee1bcdd2a8d7249a756774f78793c1">customFilter</a> )(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex, struct <a class="el" href="structtjtransform.html">tjtransform</a> *transform)</td></tr>
-<tr class="memdesc:a43ee1bcdd2a8d7249a756774f78793c1"><td class="mdescLeft">&#160;</td><td class="mdescRight">A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image.  <a href="#a43ee1bcdd2a8d7249a756774f78793c1">More...</a><br/></td></tr>
-<tr class="separator:a43ee1bcdd2a8d7249a756774f78793c1"><td class="memSeparator" colspan="2">&#160;</td></tr>
-</table>
-<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
-<div class="textblock"><p>Lossless transform. </p>
-</div><h2 class="groupheader">Field Documentation</h2>
-<a class="anchor" id="a43ee1bcdd2a8d7249a756774f78793c1"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int(* tjtransform::customFilter)(short *coeffs, <a class="el" href="structtjregion.html">tjregion</a> arrayRegion, <a class="el" href="structtjregion.html">tjregion</a> planeRegion, int componentIndex, int transformIndex, struct <a class="el" href="structtjtransform.html">tjtransform</a> *transform)</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image. </p>
-<p>This allows for custom filters or other transformations to be applied in the frequency domain.</p>
-<dl class="params"><dt>Parameters</dt><dd>
-  <table class="params">
-    <tr><td class="paramname">coeffs</td><td>pointer to an array of transformed DCT coefficients. (NOTE: this pointer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to another function or library should make a copy of them within the body of the callback.)</td></tr>
-    <tr><td class="paramname">arrayRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure containing the width and height of the array pointed to by <code>coeffs</code> as well as its offset relative to the component plane. TurboJPEG implementations may choose to split each component plane into multiple DCT coefficient arrays and call the callback function once for each array.</td></tr>
-    <tr><td class="paramname">planeRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure containing the width and height of the component plane to which <code>coeffs</code> belongs</td></tr>
-    <tr><td class="paramname">componentID</td><td>ID number of the component plane to which <code>coeffs</code> belongs (Y, Cb, and Cr have, respectively, ID's of 0, 1, and 2 in typical JPEG images.)</td></tr>
-    <tr><td class="paramname">transformID</td><td>ID number of the transformed image to which <code>coeffs</code> belongs. This is the same as the index of the transform in the <code>transforms</code> array that was passed to <a class="el" href="group___turbo_j_p_e_g.html#ga9cb8abf4cc91881e04a0329b2270be25" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a>.</td></tr>
-    <tr><td class="paramname">transform</td><td>a pointer to a <a class="el" href="structtjtransform.html" title="Lossless transform.">tjtransform</a> structure that specifies the parameters and/or cropping region for this transform</td></tr>
-  </table>
-  </dd>
-</dl>
-<dl class="section return"><dt>Returns</dt><dd>0 if the callback was successful, or -1 if an error occurred. </dd></dl>
-
-</div>
-</div>
-<a class="anchor" id="a688fe8f1a8ecc12a538d9e561cf338e3"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">void* tjtransform::data</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Arbitrary data that can be accessed within the body of the callback function. </p>
-
-</div>
-</div>
-<a class="anchor" id="a2525aab4ba6978a1c273f74fef50e498"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjtransform::op</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>One of the <a class="el" href="group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866">transform operations</a>. </p>
-
-</div>
-</div>
-<a class="anchor" id="ac0e74655baa4402209a21e1ae481c8f6"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname">int tjtransform::options</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>The bitwise OR of one of more of the <a class="el" href="group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2">transform options</a>. </p>
-
-</div>
-</div>
-<a class="anchor" id="ac324e5e442abec8a961e5bf219db12cf"></a>
-<div class="memitem">
-<div class="memproto">
-      <table class="memname">
-        <tr>
-          <td class="memname"><a class="el" href="structtjregion.html">tjregion</a> tjtransform::r</td>
-        </tr>
-      </table>
-</div><div class="memdoc">
-
-<p>Cropping region. </p>
-
-</div>
-</div>
-<hr/>The documentation for this struct was generated from the following file:<ul>
-<li>turbojpeg.h</li>
-</ul>
-</div><!-- contents -->
-<!-- start footer part -->
-<hr class="footer"/><address class="footer"><small>
-Generated by &#160;<a href="http://www.doxygen.org/index.html">
-<img class="footer" src="doxygen.png" alt="doxygen"/>
-</a> 1.8.3.1
-</small></address>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/doc/html/sync_off.png b/src/third_party/libjpeg-turbo/doc/html/sync_off.png
deleted file mode 100644
index 3b443fc..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/sync_off.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/sync_on.png b/src/third_party/libjpeg-turbo/doc/html/sync_on.png
deleted file mode 100644
index e08320f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/sync_on.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/tab_a.png b/src/third_party/libjpeg-turbo/doc/html/tab_a.png
deleted file mode 100644
index 3b725c4..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/tab_a.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/tab_b.png b/src/third_party/libjpeg-turbo/doc/html/tab_b.png
deleted file mode 100644
index e2b4a86..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/tab_b.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/tab_h.png b/src/third_party/libjpeg-turbo/doc/html/tab_h.png
deleted file mode 100644
index fd5cb70..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/tab_h.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/tab_s.png b/src/third_party/libjpeg-turbo/doc/html/tab_s.png
deleted file mode 100644
index ab478c9..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/tab_s.png
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/doc/html/tabs.css b/src/third_party/libjpeg-turbo/doc/html/tabs.css
deleted file mode 100644
index 9cf578f..0000000
--- a/src/third_party/libjpeg-turbo/doc/html/tabs.css
+++ /dev/null
@@ -1,60 +0,0 @@
-.tabs, .tabs2, .tabs3 {
-    background-image: url('tab_b.png');
-    width: 100%;
-    z-index: 101;
-    font-size: 13px;
-    font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
-}
-
-.tabs2 {
-    font-size: 10px;
-}
-.tabs3 {
-    font-size: 9px;
-}
-
-.tablist {
-    margin: 0;
-    padding: 0;
-    display: table;
-}
-
-.tablist li {
-    float: left;
-    display: table-cell;
-    background-image: url('tab_b.png');
-    line-height: 36px;
-    list-style: none;
-}
-
-.tablist a {
-    display: block;
-    padding: 0 20px;
-    font-weight: bold;
-    background-image:url('tab_s.png');
-    background-repeat:no-repeat;
-    background-position:right;
-    color: #283A5D;
-    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
-    text-decoration: none;
-    outline: none;
-}
-
-.tabs3 .tablist a {
-    padding: 0 10px;
-}
-
-.tablist a:hover {
-    background-image: url('tab_h.png');
-    background-repeat:repeat-x;
-    color: #fff;
-    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
-    text-decoration: none;
-}
-
-.tablist li.current a {
-    background-image: url('tab_a.png');
-    background-repeat:repeat-x;
-    color: #fff;
-    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
-}
diff --git a/src/third_party/libjpeg-turbo/doxygen-extra.css b/src/third_party/libjpeg-turbo/doxygen-extra.css
deleted file mode 100644
index f1bd4c2..0000000
--- a/src/third_party/libjpeg-turbo/doxygen-extra.css
+++ /dev/null
@@ -1,3 +0,0 @@
-code {
-	color: #4665A2;
-}
diff --git a/src/third_party/libjpeg-turbo/doxygen.config b/src/third_party/libjpeg-turbo/doxygen.config
deleted file mode 100644
index cb884f9..0000000
--- a/src/third_party/libjpeg-turbo/doxygen.config
+++ /dev/null
@@ -1,16 +0,0 @@
-PROJECT_NAME = TurboJPEG
-PROJECT_NUMBER = 2.0
-OUTPUT_DIRECTORY = doc/
-USE_WINDOWS_ENCODING = NO
-OPTIMIZE_OUTPUT_FOR_C = YES
-WARN_NO_PARAMDOC = YES
-GENERATE_LATEX = NO
-FILE_PATTERNS = turbojpeg.h
-HIDE_UNDOC_MEMBERS = YES
-VERBATIM_HEADERS = NO
-EXTRACT_STATIC = YES
-JAVADOC_AUTOBRIEF = YES
-MAX_INITIALIZER_LINES = 0
-ALWAYS_DETAILED_SEC = YES
-HTML_TIMESTAMP = NO
-HTML_EXTRA_STYLESHEET = doxygen-extra.css
diff --git a/src/third_party/libjpeg-turbo/example.txt b/src/third_party/libjpeg-turbo/example.txt
deleted file mode 100644
index 04c11fe..0000000
--- a/src/third_party/libjpeg-turbo/example.txt
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * example.txt
- *
- * This file illustrates how to use the IJG code as a subroutine library
- * to read or write JPEG image files.  You should look at this code in
- * conjunction with the documentation file libjpeg.txt.
- *
- * This code will not do anything useful as-is, but it may be helpful as a
- * skeleton for constructing routines that call the JPEG library.
- *
- * We present these routines in the same coding style used in the JPEG code
- * (ANSI function definitions, etc); but you are of course free to code your
- * routines in a different style if you prefer.
- */
-
-/* This example was part of the original libjpeg documentation and has been
- * unchanged since 1994.  It is, as described in libjpeg.txt, "heavily
- * commented skeleton code for calling the JPEG library."  It is not meant to
- * be compiled as a standalone program, since it has no main() function and
- * does not compress from/decompress to a real image buffer (corollary:
- * put_scanline_someplace() is not a real function.)  First-time users of
- * libjpeg-turbo would be better served by looking at tjexample.c, which uses
- * the more straightforward TurboJPEG API, or at cjpeg.c and djpeg.c, which are
- * examples of libjpeg API usage that can be (and are) compiled into standalone
- * programs.  Note that this example, as well as the examples in cjpeg.c and
- * djpeg.c, interleave disk I/O with JPEG compression/decompression, so none of
- * these examples is suitable for benchmarking purposes.
- */
-
-#include <stdio.h>
-
-/*
- * Include file for users of JPEG library.
- * You will need to have included system headers that define at least
- * the typedefs FILE and size_t before you can include jpeglib.h.
- * (stdio.h is sufficient on ANSI-conforming systems.)
- * You may also wish to include "jerror.h".
- */
-
-#include "jpeglib.h"
-
-/*
- * <setjmp.h> is used for the optional error recovery mechanism shown in
- * the second part of the example.
- */
-
-#include <setjmp.h>
-
-
-
-/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
-
-/* This half of the example shows how to feed data into the JPEG compressor.
- * We present a minimal version that does not worry about refinements such
- * as error recovery (the JPEG code will just exit() if it gets an error).
- */
-
-
-/*
- * IMAGE DATA FORMATS:
- *
- * The standard input image format is a rectangular array of pixels, with
- * each pixel having the same number of "component" values (color channels).
- * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
- * If you are working with color data, then the color values for each pixel
- * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
- * RGB color.
- *
- * For this example, we'll assume that this data structure matches the way
- * our application has stored the image in memory, so we can just pass a
- * pointer to our image buffer.  In particular, let's say that the image is
- * RGB color and is described by:
- */
-
-extern JSAMPLE *image_buffer;   /* Points to large array of R,G,B-order data */
-extern int image_height;        /* Number of rows in image */
-extern int image_width;         /* Number of columns in image */
-
-
-/*
- * Sample routine for JPEG compression.  We assume that the target file name
- * and a compression quality factor are passed in.
- */
-
-GLOBAL(void)
-write_JPEG_file(char *filename, int quality)
-{
-  /* This struct contains the JPEG compression parameters and pointers to
-   * working space (which is allocated as needed by the JPEG library).
-   * It is possible to have several such structures, representing multiple
-   * compression/decompression processes, in existence at once.  We refer
-   * to any one struct (and its associated working data) as a "JPEG object".
-   */
-  struct jpeg_compress_struct cinfo;
-  /* This struct represents a JPEG error handler.  It is declared separately
-   * because applications often want to supply a specialized error handler
-   * (see the second half of this file for an example).  But here we just
-   * take the easy way out and use the standard error handler, which will
-   * print a message on stderr and call exit() if compression fails.
-   * Note that this struct must live as long as the main JPEG parameter
-   * struct, to avoid dangling-pointer problems.
-   */
-  struct jpeg_error_mgr jerr;
-  /* More stuff */
-  FILE *outfile;                /* target file */
-  JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
-  int row_stride;               /* physical row width in image buffer */
-
-  /* Step 1: allocate and initialize JPEG compression object */
-
-  /* We have to set up the error handler first, in case the initialization
-   * step fails.  (Unlikely, but it could happen if you are out of memory.)
-   * This routine fills in the contents of struct jerr, and returns jerr's
-   * address which we place into the link field in cinfo.
-   */
-  cinfo.err = jpeg_std_error(&jerr);
-  /* Now we can initialize the JPEG compression object. */
-  jpeg_create_compress(&cinfo);
-
-  /* Step 2: specify data destination (eg, a file) */
-  /* Note: steps 2 and 3 can be done in either order. */
-
-  /* Here we use the library-supplied code to send compressed data to a
-   * stdio stream.  You can also write your own code to do something else.
-   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
-   * requires it in order to write binary files.
-   */
-  if ((outfile = fopen(filename, "wb")) == NULL) {
-    fprintf(stderr, "can't open %s\n", filename);
-    exit(1);
-  }
-  jpeg_stdio_dest(&cinfo, outfile);
-
-  /* Step 3: set parameters for compression */
-
-  /* First we supply a description of the input image.
-   * Four fields of the cinfo struct must be filled in:
-   */
-  cinfo.image_width = image_width;      /* image width and height, in pixels */
-  cinfo.image_height = image_height;
-  cinfo.input_components = 3;           /* # of color components per pixel */
-  cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */
-  /* Now use the library's routine to set default compression parameters.
-   * (You must set at least cinfo.in_color_space before calling this,
-   * since the defaults depend on the source color space.)
-   */
-  jpeg_set_defaults(&cinfo);
-  /* Now you can set any non-default parameters you wish to.
-   * Here we just illustrate the use of quality (quantization table) scaling:
-   */
-  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
-
-  /* Step 4: Start compressor */
-
-  /* TRUE ensures that we will write a complete interchange-JPEG file.
-   * Pass TRUE unless you are very sure of what you're doing.
-   */
-  jpeg_start_compress(&cinfo, TRUE);
-
-  /* Step 5: while (scan lines remain to be written) */
-  /*           jpeg_write_scanlines(...); */
-
-  /* Here we use the library's state variable cinfo.next_scanline as the
-   * loop counter, so that we don't have to keep track ourselves.
-   * To keep things simple, we pass one scanline per call; you can pass
-   * more if you wish, though.
-   */
-  row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
-
-  while (cinfo.next_scanline < cinfo.image_height) {
-    /* jpeg_write_scanlines expects an array of pointers to scanlines.
-     * Here the array is only one element long, but you could pass
-     * more than one scanline at a time if that's more convenient.
-     */
-    row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
-    (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
-  }
-
-  /* Step 6: Finish compression */
-
-  jpeg_finish_compress(&cinfo);
-  /* After finish_compress, we can close the output file. */
-  fclose(outfile);
-
-  /* Step 7: release JPEG compression object */
-
-  /* This is an important step since it will release a good deal of memory. */
-  jpeg_destroy_compress(&cinfo);
-
-  /* And we're done! */
-}
-
-
-/*
- * SOME FINE POINTS:
- *
- * In the above loop, we ignored the return value of jpeg_write_scanlines,
- * which is the number of scanlines actually written.  We could get away
- * with this because we were only relying on the value of cinfo.next_scanline,
- * which will be incremented correctly.  If you maintain additional loop
- * variables then you should be careful to increment them properly.
- * Actually, for output to a stdio stream you needn't worry, because
- * then jpeg_write_scanlines will write all the lines passed (or else exit
- * with a fatal error).  Partial writes can only occur if you use a data
- * destination module that can demand suspension of the compressor.
- * (If you don't know what that's for, you don't need it.)
- *
- * If the compressor requires full-image buffers (for entropy-coding
- * optimization or a multi-scan JPEG file), it will create temporary
- * files for anything that doesn't fit within the maximum-memory setting.
- * (Note that temp files are NOT needed if you use the default parameters.)
- * On some systems you may need to set up a signal handler to ensure that
- * temporary files are deleted if the program is interrupted.  See libjpeg.txt.
- *
- * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
- * files to be compatible with everyone else's.  If you cannot readily read
- * your data in that order, you'll need an intermediate array to hold the
- * image.  See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
- * source data using the JPEG code's internal virtual-array mechanisms.
- */
-
-
-
-/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
-
-/* This half of the example shows how to read data from the JPEG decompressor.
- * It's a bit more refined than the above, in that we show:
- *   (a) how to modify the JPEG library's standard error-reporting behavior;
- *   (b) how to allocate workspace using the library's memory manager.
- *
- * Just to make this example a little different from the first one, we'll
- * assume that we do not intend to put the whole image into an in-memory
- * buffer, but to send it line-by-line someplace else.  We need a one-
- * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
- * memory manager allocate it for us.  This approach is actually quite useful
- * because we don't need to remember to deallocate the buffer separately: it
- * will go away automatically when the JPEG object is cleaned up.
- */
-
-
-/*
- * ERROR HANDLING:
- *
- * The JPEG library's standard error handler (jerror.c) is divided into
- * several "methods" which you can override individually.  This lets you
- * adjust the behavior without duplicating a lot of code, which you might
- * have to update with each future release.
- *
- * Our example here shows how to override the "error_exit" method so that
- * control is returned to the library's caller when a fatal error occurs,
- * rather than calling exit() as the standard error_exit method does.
- *
- * We use C's setjmp/longjmp facility to return control.  This means that the
- * routine which calls the JPEG library must first execute a setjmp() call to
- * establish the return point.  We want the replacement error_exit to do a
- * longjmp().  But we need to make the setjmp buffer accessible to the
- * error_exit routine.  To do this, we make a private extension of the
- * standard JPEG error handler object.  (If we were using C++, we'd say we
- * were making a subclass of the regular error handler.)
- *
- * Here's the extended error handler struct:
- */
-
-struct my_error_mgr {
-  struct jpeg_error_mgr pub;    /* "public" fields */
-
-  jmp_buf setjmp_buffer;        /* for return to caller */
-};
-
-typedef struct my_error_mgr *my_error_ptr;
-
-/*
- * Here's the routine that will replace the standard error_exit method:
- */
-
-METHODDEF(void)
-my_error_exit(j_common_ptr cinfo)
-{
-  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
-  my_error_ptr myerr = (my_error_ptr)cinfo->err;
-
-  /* Always display the message. */
-  /* We could postpone this until after returning, if we chose. */
-  (*cinfo->err->output_message) (cinfo);
-
-  /* Return control to the setjmp point */
-  longjmp(myerr->setjmp_buffer, 1);
-}
-
-
-/*
- * Sample routine for JPEG decompression.  We assume that the source file name
- * is passed in.  We want to return 1 on success, 0 on error.
- */
-
-
-GLOBAL(int)
-read_JPEG_file(char *filename)
-{
-  /* This struct contains the JPEG decompression parameters and pointers to
-   * working space (which is allocated as needed by the JPEG library).
-   */
-  struct jpeg_decompress_struct cinfo;
-  /* We use our private extension JPEG error handler.
-   * Note that this struct must live as long as the main JPEG parameter
-   * struct, to avoid dangling-pointer problems.
-   */
-  struct my_error_mgr jerr;
-  /* More stuff */
-  FILE *infile;                 /* source file */
-  JSAMPARRAY buffer;            /* Output row buffer */
-  int row_stride;               /* physical row width in output buffer */
-
-  /* In this example we want to open the input file before doing anything else,
-   * so that the setjmp() error recovery below can assume the file is open.
-   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
-   * requires it in order to read binary files.
-   */
-
-  if ((infile = fopen(filename, "rb")) == NULL) {
-    fprintf(stderr, "can't open %s\n", filename);
-    return 0;
-  }
-
-  /* Step 1: allocate and initialize JPEG decompression object */
-
-  /* We set up the normal JPEG error routines, then override error_exit. */
-  cinfo.err = jpeg_std_error(&jerr.pub);
-  jerr.pub.error_exit = my_error_exit;
-  /* Establish the setjmp return context for my_error_exit to use. */
-  if (setjmp(jerr.setjmp_buffer)) {
-    /* If we get here, the JPEG code has signaled an error.
-     * We need to clean up the JPEG object, close the input file, and return.
-     */
-    jpeg_destroy_decompress(&cinfo);
-    fclose(infile);
-    return 0;
-  }
-  /* Now we can initialize the JPEG decompression object. */
-  jpeg_create_decompress(&cinfo);
-
-  /* Step 2: specify data source (eg, a file) */
-
-  jpeg_stdio_src(&cinfo, infile);
-
-  /* Step 3: read file parameters with jpeg_read_header() */
-
-  (void)jpeg_read_header(&cinfo, TRUE);
-  /* We can ignore the return value from jpeg_read_header since
-   *   (a) suspension is not possible with the stdio data source, and
-   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
-   * See libjpeg.txt for more info.
-   */
-
-  /* Step 4: set parameters for decompression */
-
-  /* In this example, we don't need to change any of the defaults set by
-   * jpeg_read_header(), so we do nothing here.
-   */
-
-  /* Step 5: Start decompressor */
-
-  (void)jpeg_start_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
-
-  /* We may need to do some setup of our own at this point before reading
-   * the data.  After jpeg_start_decompress() we have the correct scaled
-   * output image dimensions available, as well as the output colormap
-   * if we asked for color quantization.
-   * In this example, we need to make an output work buffer of the right size.
-   */
-  /* JSAMPLEs per row in output buffer */
-  row_stride = cinfo.output_width * cinfo.output_components;
-  /* Make a one-row-high sample array that will go away when done with image */
-  buffer = (*cinfo.mem->alloc_sarray)
-                ((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
-
-  /* Step 6: while (scan lines remain to be read) */
-  /*           jpeg_read_scanlines(...); */
-
-  /* Here we use the library's state variable cinfo.output_scanline as the
-   * loop counter, so that we don't have to keep track ourselves.
-   */
-  while (cinfo.output_scanline < cinfo.output_height) {
-    /* jpeg_read_scanlines expects an array of pointers to scanlines.
-     * Here the array is only one element long, but you could ask for
-     * more than one scanline at a time if that's more convenient.
-     */
-    (void)jpeg_read_scanlines(&cinfo, buffer, 1);
-    /* Assume put_scanline_someplace wants a pointer and sample count. */
-    put_scanline_someplace(buffer[0], row_stride);
-  }
-
-  /* Step 7: Finish decompression */
-
-  (void)jpeg_finish_decompress(&cinfo);
-  /* We can ignore the return value since suspension is not possible
-   * with the stdio data source.
-   */
-
-  /* Step 8: Release JPEG decompression object */
-
-  /* This is an important step since it will release a good deal of memory. */
-  jpeg_destroy_decompress(&cinfo);
-
-  /* After finish_decompress, we can close the input file.
-   * Here we postpone it until after no more JPEG errors are possible,
-   * so as to simplify the setjmp error logic above.  (Actually, I don't
-   * think that jpeg_destroy can do an error exit, but why assume anything...)
-   */
-  fclose(infile);
-
-  /* At this point you may want to check to see whether any corrupt-data
-   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
-   */
-
-  /* And we're done! */
-  return 1;
-}
-
-
-/*
- * SOME FINE POINTS:
- *
- * In the above code, we ignored the return value of jpeg_read_scanlines,
- * which is the number of scanlines actually read.  We could get away with
- * this because we asked for only one line at a time and we weren't using
- * a suspending data source.  See libjpeg.txt for more info.
- *
- * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
- * we should have done it beforehand to ensure that the space would be
- * counted against the JPEG max_memory setting.  In some systems the above
- * code would risk an out-of-memory error.  However, in general we don't
- * know the output image dimensions before jpeg_start_decompress(), unless we
- * call jpeg_calc_output_dimensions().  See libjpeg.txt for more about this.
- *
- * Scanlines are returned in the same order as they appear in the JPEG file,
- * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
- * you can use one of the virtual arrays provided by the JPEG memory manager
- * to invert the data.  See wrbmp.c for an example.
- *
- * As with compression, some operating modes may require temporary files.
- * On some systems you may need to set up a signal handler to ensure that
- * temporary files are deleted if the program is interrupted.  See libjpeg.txt.
- */
diff --git a/src/third_party/libjpeg-turbo/gtest/cjpeg-gtest-wrapper.cpp b/src/third_party/libjpeg-turbo/gtest/cjpeg-gtest-wrapper.cpp
new file mode 100644
index 0000000..9a5e08c
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/cjpeg-gtest-wrapper.cpp
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "gtest-utils.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+extern "C" int cjpeg(int argc, char *argv[]);
+
+TEST(CJPEGTest, RGBISlow) {
+
+  base::FilePath icc_path;
+  GetTestFilePath(&icc_path, "test1.icc");
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_rgb_islow.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-rgb";
+  std::string arg2 = "-dct";
+  std::string arg3 = "int";
+  std::string arg4 = "-icc";
+  std::string arg5 = icc_path.MaybeAsASCII();
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0],
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "1d44a406f61da743b5fd31c0a9abdca3";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, IFastOpt422) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_422_ifast_opt.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "2x1";
+  std::string arg3 = "-dct";
+  std::string arg4 = "fast";
+  std::string arg5 = "-opt";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0],
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "2540287b79d913f91665e660303ab2c8";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, IFastProg420Q100) {
+
+  base::FilePath scans_path;
+  GetTestFilePath(&scans_path, "test.scan");
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_q100_ifast_prog.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "2x2";
+  std::string arg3 = "-quality";
+  std::string arg4 = "100";
+  std::string arg5 = "-dct";
+  std::string arg6 = "fast";
+  std::string arg7 = "-scans";
+  std::string arg8 = scans_path.MaybeAsASCII();
+  std::string arg9 = "-outfile";
+  std::string arg10 = output_path.MaybeAsASCII();
+  std::string arg11 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0], &arg10[0],
+                           &arg11[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(12, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "0ba15f9dab81a703505f835f9dbbac6d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, GrayISlow) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_gray_islow.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-gray";
+  std::string arg2 = "-dct";
+  std::string arg3 = "int";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0],
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "72b51f894b8f4a10b3ee3066770aa38d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, IFastOpt420S) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420s_ifast_opt.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "2x2";
+  std::string arg3 = "-smooth";
+  std::string arg4 = "1";
+  std::string arg5 = "-dct";
+  std::string arg6 = "int";
+  std::string arg7 = "-opt";
+  std::string arg8 = "-outfile";
+  std::string arg9 = output_path.MaybeAsASCII();
+  std::string arg10 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0], &arg10[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(11, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "388708217ac46273ca33086b22827ed8";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, FloatProg3x2) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_3x2_float_prog.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "3x2";
+  std::string arg3 = "-dct";
+  std::string arg4 = "float";
+  std::string arg5 = "-prog";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+#if defined(WITH_SIMD) && (defined(__i386__) || defined(__x86_64__))
+  const std::string EXPECTED_MD5 = "343e3f8caf8af5986ebaf0bdc13b5c71";
+#else
+  const std::string EXPECTED_MD5 = "9bca803d2042bd1eb03819e2bf92b3e5";
+#endif
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, IFastProg3x2) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_3x2_ifast_prog.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "3x2";
+  std::string arg3 = "-dct";
+  std::string arg4 = "fast";
+  std::string arg5 = "-prog";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "1ee5d2c1a77f2da495f993c8c7cceca5";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+#ifdef C_ARITH_CODING_SUPPORTED
+TEST(CJPEGTest, ISlowAri420) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_ari.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-arithmetic";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "e986fb0a637a8d833d96e8a6d6d84ea1";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, ISlowProgAri444) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_444_islow_progari.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-sample";
+  std::string arg2 = "1x1";
+  std::string arg3 = "-dct";
+  std::string arg4 = "int";
+  std::string arg5 = "-prog";
+  std::string arg6 = "-arithmetic";
+  std::string arg7 = "-outfile";
+  std::string arg8 = output_path.MaybeAsASCII();
+  std::string arg9 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(10, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "0a8f1c8f66e113c3cf635df0a475a617";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, ISlowAri444) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_444_islow_ari.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-arithmetic";
+  std::string arg4 = "-sample";
+  std::string arg5 = "1x1";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "dd1b827fc504feb0259894e7132585b4";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+#endif
+
+TEST(CJPEGTest, ISlowProg420) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_prog.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-prog";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "1c4afddc05c0a43489ee54438a482d92";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, ISlow444) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_444_islow.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-sample";
+  std::string arg4 = "1x1";
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "62a8665a2e08e90c6fffa3a94b894ce2";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(CJPEGTest, ISlowProg444) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.ppm");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_444_islow_prog.jpg");
+
+  std::string prog_name = "cjpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-prog";
+  std::string arg4 = "-sample";
+  std::string arg5 = "1x1";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(cjpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "666ef192fff72570e332db7610e1a7d1";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
diff --git a/src/third_party/libjpeg-turbo/gtest/djpeg-gtest-wrapper.cpp b/src/third_party/libjpeg-turbo/gtest/djpeg-gtest-wrapper.cpp
new file mode 100644
index 0000000..933fb6f
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/djpeg-gtest-wrapper.cpp
@@ -0,0 +1,901 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "gtest-utils.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+extern "C" int djpeg(int argc, char *argv[]);
+
+const static std::vector<std::tuple<const std::string,
+                                    const std::string,
+                                    const std::string>> SCALE_IMAGE_MD5 = {
+  std::make_tuple("2/1", "testout_420m_islow_2_1.ppm",
+                  "9f9de8c0612f8d06869b960b05abf9c9"),
+  std::make_tuple("15/8", "testout_420m_islow_15_8.ppm",
+                  "b6875bc070720b899566cc06459b63b7"),
+  std::make_tuple("13/8", "testout_420m_islow_13_8.ppm",
+                  "bc3452573c8152f6ae552939ee19f82f"),
+  std::make_tuple("11/8", "testout_420m_islow_11_8.ppm",
+                  "d8cc73c0aaacd4556569b59437ba00a5"),
+  std::make_tuple("9/8", "testout_420m_islow_9_8.ppm",
+                  "d25e61bc7eac0002f5b393aa223747b6"),
+  std::make_tuple("7/8", "testout_420m_islow_7_8.ppm",
+                  "ddb564b7c74a09494016d6cd7502a946"),
+  std::make_tuple("3/4", "testout_420m_islow_3_4.ppm",
+                  "8ed8e68808c3fbc4ea764fc9d2968646"),
+  std::make_tuple("5/8", "testout_420m_islow_5_8.ppm",
+                  "a3363274999da2366a024efae6d16c9b"),
+  std::make_tuple("1/2", "testout_420m_islow_1_2.ppm",
+                  "e692a315cea26b988c8e8b29a5dbcd81"),
+  std::make_tuple("3/8", "testout_420m_islow_3_8.ppm",
+                  "79eca9175652ced755155c90e785a996"),
+  std::make_tuple("1/4", "testout_420m_islow_1_4.ppm",
+                  "79cd778f8bf1a117690052cacdd54eca"),
+  std::make_tuple("1/8", "testout_420m_islow_1_8.ppm",
+                  "391b3d4aca640c8567d6f8745eb2142f")
+};
+
+class DJPEGTestScalingDCT : public
+  ::testing::TestWithParam<std::tuple<const std::string,
+                                      const std::string,
+                                      const std::string>> {};
+
+TEST_P(DJPEGTestScalingDCT, Test) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(std::get<1>(GetParam()));
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-scale";
+  std::string arg4 = std::get<0>(GetParam());
+  std::string arg5 = "-nosmooth";
+  std::string arg6 = "-ppm";
+  std::string arg7 = "-outfile";
+  std::string arg8 = output_path.MaybeAsASCII();
+  std::string arg9 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(10, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  EXPECT_TRUE(CompareFileAndMD5(output_path, std::get<2>(GetParam())));
+}
+
+INSTANTIATE_TEST_SUITE_P(TestScalingDCT,
+                         DJPEGTestScalingDCT,
+                         ::testing::ValuesIn(SCALE_IMAGE_MD5));
+
+TEST(DJPEGTest, ISlow420256) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_256.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-colors";
+  std::string arg4 = "256";
+  std::string arg5 = "-bmp";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "4980185e3776e89bd931736e1cddeee6";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420565) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_565.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-dither";
+  std::string arg5 = "none";
+  std::string arg6 = "-bmp";
+  std::string arg7 = "-outfile";
+  std::string arg8 = output_path.MaybeAsASCII();
+  std::string arg9 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(10, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "bf9d13e16c4923b92e1faa604d7922cb";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420565D) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_565D.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-bmp";
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "6bde71526acc44bcff76f696df8638d2";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420M565) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420m_islow_565.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-rgb565";
+  std::string arg5 = "-dither";
+  std::string arg6 = "none";
+  std::string arg7 = "-bmp";
+  std::string arg8 = "-outfile";
+  std::string arg9 = output_path.MaybeAsASCII();
+  std::string arg10 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0], &arg10[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(11, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "8dc0185245353cfa32ad97027342216f";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420M565D) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420m_islow_565D.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-rgb565";
+  std::string arg5 = "-bmp";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "ce034037d212bc403330df6f915c161b";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420Skip1531) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_skip15_31.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-skip";
+  std::string arg4 = "15,31";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "c4c65c1e43d7275cd50328a61e6534f0";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+#ifdef C_ARITH_CODING_SUPPORTED
+TEST(DJPEGTest, ISlow420AriSkip16139) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testimgari.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(
+                              "testout_420_islow_ari_skip16_139.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-skip";
+  std::string arg4 = "16,139";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "087c6b123db16ac00cb88c5b590bb74a";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow420AriCrop53x5344) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testimgari.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(
+                              "testout_420_islow_ari_crop53x53_4_4.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-crop";
+  std::string arg4 = "53x53+4+4";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "886c6775af22370257122f8b16207e6d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFast420MAri) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testimgari.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420m_ifast_ari.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-fast";
+  std::string arg2 = "-ppm";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "72b59a99bcf1de24c5b27d151bde2437";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow444AriCrop37x3700) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_444_islow_ari.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(
+                              "testout_444_islow_ari_crop37x37_0_0.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-crop";
+  std::string arg4 = "37x37+0+0";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "cb57b32bd6d03e35432362f7bf184b6d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+#endif
+
+TEST(DJPEGTest, RGBISlow) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_rgb_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_rgb_islow.ppm");
+  base::FilePath output_icc_path(GetTargetDirectory());
+  output_icc_path = output_icc_path.AppendASCII("testout_rgb_islow.icc");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-ppm";
+  std::string arg4 = "-icc";
+  std::string arg5 = output_icc_path.MaybeAsASCII();
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "00a257f5393fef8821f2b88ac7421291";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+  const std::string ICC_EXPECTED_MD5 = "b06a39d730129122e85c1363ed1bbc9e";
+  EXPECT_TRUE(CompareFileAndMD5(output_icc_path, ICC_EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, RGBISlow565) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_rgb_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_rgb_islow_565.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-dither";
+  std::string arg5 = "none";
+  std::string arg6 = "-bmp";
+  std::string arg7 = "-outfile";
+  std::string arg8 = output_path.MaybeAsASCII();
+  std::string arg9 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(10, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "f07d2e75073e4bb10f6c6f4d36e2e3be";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, RGBISlow565D) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_rgb_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_rgb_islow_565D.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-bmp";
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "4cfa0928ef3e6bb626d7728c924cfda4";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFast422) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_422_ifast_opt.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_422_ifast.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "fast";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "35bd6b3f833bad23de82acea847129fa";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFast422M) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_422_ifast_opt.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_422m_ifast.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "fast";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "8dbc65323d62cca7c91ba02dd1cfa81d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFast422M565) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_422_ifast_opt.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_422m_ifast_565.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-rgb565";
+  std::string arg5 = "-dither";
+  std::string arg6 = "none";
+  std::string arg7 = "-bmp";
+  std::string arg8 = "-outfile";
+  std::string arg9 = output_path.MaybeAsASCII();
+  std::string arg10 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0], &arg10[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(11, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "3294bd4d9a1f2b3d08ea6020d0db7065";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFast422M565D) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_422_ifast_opt.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_422m_ifast_565D.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-rgb565";
+  std::string arg5 = "-bmp";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "da98c9c7b6039511be4a79a878a9abc1";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFastProg420Q100) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_420_q100_ifast_prog.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_q100_ifast.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "fast";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "5a732542015c278ff43635e473a8a294";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFastProg420MQ100) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_420_q100_ifast_prog.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420m_q100_ifast.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "fast";
+  std::string arg3 = "-nosmooth";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "ff692ee9323a3b424894862557c092f1";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, GrayISlow) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_gray_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_gray_islow.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "8d3596c56eace32f205deccc229aa5ed";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, GrayISlowRGB) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_gray_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_gray_islow_rgb.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb";
+  std::string arg4 = "-outfile";
+  std::string arg5 = output_path.MaybeAsASCII();
+  std::string arg6 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(7, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "116424ac07b79e5e801f00508eab48ec";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, GrayISlow565) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_gray_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_gray_islow_565.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-dither";
+  std::string arg5 = "none";
+  std::string arg6 = "-bmp";
+  std::string arg7 = "-outfile";
+  std::string arg8 = output_path.MaybeAsASCII();
+  std::string arg9 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0], &arg9[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(10, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "12f78118e56a2f48b966f792fedf23cc";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, GrayISlow565D) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_gray_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_gray_islow_565D.bmp");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-rgb565";
+  std::string arg4 = "-bmp";
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "bdbbd616441a24354c98553df5dc82db";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, FloatProg3x2) {
+
+  base::FilePath input_image_path;
+#if defined(WITH_SIMD) && (defined(__i386__) || defined(__x86_64__))
+  GetTestFilePath(&input_image_path, "testout_3x2_float_prog_sse.jpg");
+#else
+  GetTestFilePath(&input_image_path, "testout_3x2_float_prog.jpg");
+#endif
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_3x2_float.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "float";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+#if defined(WITH_SIMD) && (defined(__i386__) || defined(__x86_64__))
+  const std::string EXPECTED_MD5 = "1a75f36e5904d6fc3a85a43da9ad89bb";
+#else
+  const std::string EXPECTED_MD5 = "f6bfab038438ed8f5522fbd33595dcdc";
+#endif
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, IFastProg3x2) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_3x2_ifast_prog.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_3x2_ifast.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "fast";
+  std::string arg3 = "-outfile";
+  std::string arg4 = output_path.MaybeAsASCII();
+  std::string arg5 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(6, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "fd283664b3b49127984af0a7f118fccd";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlowProgCrop62x627171) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_420_islow_prog.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(
+                              "testout_420_islow_prog_crop62x62_71_71.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-crop";
+  std::string arg4 = "62x62+71+71";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "26eb36ccc7d1f0cb80cdabb0ac8b5d99";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlow444Skip16) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_444_islow.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_444_islow_skip1_6.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-skip";
+  std::string arg4 = "1,6";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "5606f86874cf26b8fcee1117a0a436a6";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(DJPEGTest, ISlowProg444Crop98x981313) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_444_islow_prog.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII(
+                              "testout_444_islow_prog_crop98x98_13_13.ppm");
+
+  std::string prog_name = "djpeg";
+  std::string arg1 = "-dct";
+  std::string arg2 = "int";
+  std::string arg3 = "-crop";
+  std::string arg4 = "98x98+13+13";
+  std::string arg5 = "-ppm";
+  std::string arg6 = "-outfile";
+  std::string arg7 = output_path.MaybeAsASCII();
+  std::string arg8 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0], &arg8[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(djpeg(9, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "db87dc7ce26bcdc7a6b56239ce2b9d6c";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
diff --git a/src/third_party/libjpeg-turbo/gtest/gtest-utils.cpp b/src/third_party/libjpeg-turbo/gtest/gtest-utils.cpp
new file mode 100644
index 0000000..b6df7ab
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/gtest-utils.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "base/strings/utf_string_conversions.h"
+#include "gtest-utils.h"
+
+#if defined(OS_WIN)
+std::wstring GetTargetDirectory() {
+  base::FilePath path;
+  base::PathService::Get(base::DIR_CURRENT, &path);
+  return base::UTF8ToWide(path.MaybeAsASCII());
+}
+#else
+std::string GetTargetDirectory() {
+#if defined(ANDROID)
+  return "/sdcard";
+#else
+  base::FilePath path;
+  base::PathService::Get(base::DIR_CURRENT, &path);
+  return path.MaybeAsASCII();
+#endif
+}
+#endif
+
+void GetTestFilePath(base::FilePath* path, const std::string filename) {
+  ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, path));
+  *path = path->AppendASCII("third_party");
+  *path = path->AppendASCII("libjpeg_turbo");
+  *path = path->AppendASCII("testimages");
+  *path = path->AppendASCII(filename);
+  ASSERT_TRUE(base::PathExists(*path));
+}
+
+bool CompareFileAndMD5(const base::FilePath& path,
+                       const std::string expected_md5) {
+  // Read the output file and compute the MD5.
+  std::string output;
+  if (!base::ReadFileToString(path, &output)) {
+    return false;
+  }
+  const std::string md5 = base::MD5String(output);
+  return expected_md5 == md5;
+}
diff --git a/src/third_party/libjpeg-turbo/gtest/gtest-utils.h b/src/third_party/libjpeg-turbo/gtest/gtest-utils.h
new file mode 100644
index 0000000..0953848
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/gtest-utils.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef THIRD_PARTY_LIBJPEG_TURBO_GTEST_UTILS_H_
+#define THIRD_PARTY_LIBJPEG_TURBO_GTEST_UTILS_H_
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/hash/md5.h"
+#include "base/path_service.h"
+#include "gtest-utils.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+// Returns the absolute path of the test output directory as a string.
+// On Android this path is /sdcard; on all other platforms it is the current
+// directory.
+#if defined(OS_WIN)
+std::wstring GetTargetDirectory();
+#else
+std::string GetTargetDirectory();
+#endif
+
+// Files used as input for libjpeg-turbo unit tests are stored in
+// <chromium>/src/third_party/libjpeg_turbo/testimages.
+// Given a test file |filename|, this function will set |path| to
+// <chromium>/src/third_party/libjpeg_turbo/testimages/filename
+// If the file does not exit an assertion will fail.
+void GetTestFilePath(base::FilePath* path,
+                     const std::string filename);
+
+// Returns true if the MD5 sum of the file at the given |path| matches that of
+// the |expected_md5|, false otherwise.
+bool CompareFileAndMD5(const base::FilePath& path,
+                       const std::string expected_md5);
+
+#endif // THIRD_PARTY_LIBJPEG_TURBO_GTEST_UTILS_H_
diff --git a/src/third_party/libjpeg-turbo/gtest/jpegtran-gtest-wrapper.cpp b/src/third_party/libjpeg-turbo/gtest/jpegtran-gtest-wrapper.cpp
new file mode 100644
index 0000000..a6a1bd8
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/jpegtran-gtest-wrapper.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "gtest-utils.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+extern "C" int jpegtran(int argc, char *argv[]);
+
+TEST(JPEGTranTest, ICC) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testout_rgb_islow.jpg");
+  base::FilePath icc_path;
+  GetTestFilePath(&icc_path, "test2.icc");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_rgb_islow2.jpg");
+
+  std::string prog_name = "jpegtran";
+  std::string arg1 = "-copy";
+  std::string arg2 = "all";
+  std::string arg3 = "-icc";
+  std::string arg4 = icc_path.MaybeAsASCII();
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(jpegtran(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "31d121e57b6c2934c890a7fc7763bcd4";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(JPEGTranTest, Crop) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testorig.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_crop.jpg");
+
+  std::string prog_name = "jpegtran";
+  std::string arg1 = "-crop";
+  std::string arg2 = "120x90+20+50";
+  std::string arg3 = "-transpose";
+  std::string arg4 = "-perfect";
+  std::string arg5 = "-outfile";
+  std::string arg6 = output_path.MaybeAsASCII();
+  std::string arg7 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                           &arg6[0], &arg7[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(jpegtran(8, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "b4197f377e621c4e9b1d20471432610d";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+#ifdef C_ARITH_CODING_SUPPORTED
+TEST(JPEGTranTest, ISlow420Ari) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testimgint.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow_ari2.jpg");
+
+  std::string prog_name = "jpegtran";
+  std::string arg1 = "-arithmetic";
+  std::string arg2 = "-outfile";
+  std::string arg3 = output_path.MaybeAsASCII();
+  std::string arg4 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0], &arg4[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(jpegtran(5, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "e986fb0a637a8d833d96e8a6d6d84ea1";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+
+TEST(JPEGTranTest, ISlow420) {
+
+  base::FilePath input_image_path;
+  GetTestFilePath(&input_image_path, "testimgari.jpg");
+  base::FilePath output_path(GetTargetDirectory());
+  output_path = output_path.AppendASCII("testout_420_islow.jpg");
+
+  std::string prog_name = "jpegtran";
+  std::string arg1 = "-outfile";
+  std::string arg2 = output_path.MaybeAsASCII();
+  std::string arg3 = input_image_path.MaybeAsASCII();
+
+  char *command_line[] = { &prog_name[0],
+                           &arg1[0], &arg2[0], &arg3[0]
+                         };
+  // Generate test image file.
+  EXPECT_EQ(jpegtran(4, command_line), 0);
+
+  // Compare expected MD5 sum against that of test image.
+  const std::string EXPECTED_MD5 = "9a68f56bc76e466aa7e52f415d0f4a5f";
+  EXPECT_TRUE(CompareFileAndMD5(output_path, EXPECTED_MD5));
+}
+#endif
diff --git a/src/third_party/libjpeg-turbo/gtest/tjbench-gtest-wrapper.cpp b/src/third_party/libjpeg-turbo/gtest/tjbench-gtest-wrapper.cpp
new file mode 100644
index 0000000..700b199
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/tjbench-gtest-wrapper.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "gtest-utils.h"
+
+#include <gtest/gtest.h>
+#include <string>
+
+extern "C" int tjbench(int argc, char *argv[]);
+
+// Test image files and their expected MD5 sums.
+const static std::vector<std::pair<const std::string,
+                                   const std::string>> IMAGE_MD5_BASELINE = {
+  { "testout_tile_GRAY_Q95_8x8.ppm", "89d3ca21213d9d864b50b4e4e7de4ca6" },
+  { "testout_tile_420_Q95_8x8.ppm", "847fceab15c5b7b911cb986cf0f71de3" },
+  { "testout_tile_422_Q95_8x8.ppm", "d83dacd9fc73b0a6f10c09acad64eb1e" },
+  { "testout_tile_444_Q95_8x8.ppm", "7964e41e67cfb8d0a587c0aa4798f9c3" },
+  { "testout_tile_GRAY_Q95_16x16.ppm", "89d3ca21213d9d864b50b4e4e7de4ca6" },
+  { "testout_tile_420_Q95_16x16.ppm", "ca45552a93687e078f7137cc4126a7b0" },
+  { "testout_tile_422_Q95_16x16.ppm", "35077fb610d72dd743b1eb0cbcfe10fb" },
+  { "testout_tile_444_Q95_16x16.ppm", "7964e41e67cfb8d0a587c0aa4798f9c3" },
+  { "testout_tile_GRAY_Q95_32x32.ppm", "89d3ca21213d9d864b50b4e4e7de4ca6" },
+  { "testout_tile_420_Q95_32x32.ppm", "d8676f1d6b68df358353bba9844f4a00" },
+  { "testout_tile_422_Q95_32x32.ppm", "e6902ed8a449ecc0f0d6f2bf945f65f7" },
+  { "testout_tile_444_Q95_32x32.ppm", "7964e41e67cfb8d0a587c0aa4798f9c3" },
+  { "testout_tile_GRAY_Q95_64x64.ppm", "89d3ca21213d9d864b50b4e4e7de4ca6" },
+  { "testout_tile_420_Q95_64x64.ppm", "4e4c1a3d7ea4bace4f868bcbe83b7050" },
+  { "testout_tile_422_Q95_64x64.ppm", "2b4502a8f316cedbde1da7bce3d2231e" },
+  { "testout_tile_444_Q95_64x64.ppm", "7964e41e67cfb8d0a587c0aa4798f9c3" },
+  { "testout_tile_GRAY_Q95_128x128.ppm", "89d3ca21213d9d864b50b4e4e7de4ca6" },
+  { "testout_tile_420_Q95_128x128.ppm", "f24c3429c52265832beab9df72a0ceae" },
+  { "testout_tile_422_Q95_128x128.ppm", "f0b5617d578f5e13c8eee215d64d4877" },
+  { "testout_tile_444_Q95_128x128.ppm", "7964e41e67cfb8d0a587c0aa4798f9c3" }
+};
+
+class TJBenchTest : public
+  ::testing::TestWithParam<std::pair<const std::string, const std::string>> {
+
+ protected:
+
+  static void SetUpTestSuite() {
+    base::FilePath resource_path;
+    ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &resource_path));
+    resource_path = resource_path.AppendASCII("third_party");
+    resource_path = resource_path.AppendASCII("libjpeg_turbo");
+    resource_path = resource_path.AppendASCII("testimages");
+    resource_path = resource_path.AppendASCII("testorig.ppm");
+    ASSERT_TRUE(base::PathExists(resource_path));
+
+    base::FilePath target_path(GetTargetDirectory());
+    target_path = target_path.AppendASCII("testout_tile.ppm");
+
+    ASSERT_TRUE(base::CopyFile(resource_path, target_path));
+
+    std::string prog_name = "tjbench";
+    std::string arg1 = target_path.MaybeAsASCII();
+    std::string arg2 = "95";
+    std::string arg3 = "-rgb";
+    std::string arg4 = "-quiet";
+    std::string arg5 = "-tile";
+    std::string arg6 = "-benchtime";
+    std::string arg7 = "0.01";
+    std::string arg8 = "-warmup";
+    std::string arg9 = "0";
+    char *command_line[] = { &prog_name[0],
+                             &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                             &arg6[0], &arg7[0], &arg8[0], &arg9[0],
+                           };
+    // Generate test image tiles.
+    EXPECT_EQ(tjbench(10, command_line), 0);
+  }
+
+};
+
+TEST_P(TJBenchTest, TestTileBaseline) {
+  // Construct path for test image file.
+  base::FilePath test_image_path(GetTargetDirectory());
+  test_image_path = test_image_path.AppendASCII(std::get<0>(GetParam()));
+  // Read test image as string and compute MD5 sum.
+  std::string test_image_data;
+  ASSERT_TRUE(base::ReadFileToString(test_image_path, &test_image_data));
+  const std::string md5 = base::MD5String(test_image_data);
+  // Compare expected MD5 sum against that of test image.
+  EXPECT_EQ(std::get<1>(GetParam()), md5);
+}
+
+INSTANTIATE_TEST_SUITE_P(TestTileBaseline,
+                         TJBenchTest,
+                         ::testing::ValuesIn(IMAGE_MD5_BASELINE));
+
+// Test image files and their expected MD5 sums.
+const static std::vector<std::pair<const std::string,
+                                   const std::string>> IMAGE_MD5_MERGED = {
+  { "testout_tilem_420_Q95_8x8.ppm", "bc25320e1f4c31ce2e610e43e9fd173c" },
+  { "testout_tilem_422_Q95_8x8.ppm", "828941d7f41cd6283abd6beffb7fd51d" },
+  { "testout_tilem_420_Q95_16x16.ppm", "75ffdf14602258c5c189522af57fa605" },
+  { "testout_tilem_422_Q95_16x16.ppm", "e877ae1324c4a280b95376f7f018172f" },
+  { "testout_tilem_420_Q95_32x32.ppm", "75ffdf14602258c5c189522af57fa605" },
+  { "testout_tilem_422_Q95_32x32.ppm", "e877ae1324c4a280b95376f7f018172f" },
+  { "testout_tilem_420_Q95_64x64.ppm", "75ffdf14602258c5c189522af57fa605" },
+  { "testout_tilem_422_Q95_64x64.ppm", "e877ae1324c4a280b95376f7f018172f" },
+  { "testout_tilem_420_Q95_128x128.ppm", "75ffdf14602258c5c189522af57fa605" },
+  { "testout_tilem_422_Q95_128x128.ppm", "e877ae1324c4a280b95376f7f018172f" }
+};
+
+class TJBenchTestMerged : public
+  ::testing::TestWithParam<std::pair<const std::string, const std::string>> {
+
+ protected:
+
+  static void SetUpTestSuite() {
+    base::FilePath resource_path;
+    ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &resource_path));
+    resource_path = resource_path.AppendASCII("third_party");
+    resource_path = resource_path.AppendASCII("libjpeg_turbo");
+    resource_path = resource_path.AppendASCII("testimages");
+    resource_path = resource_path.AppendASCII("testorig.ppm");
+    ASSERT_TRUE(base::PathExists(resource_path));
+
+    base::FilePath target_path(GetTargetDirectory());
+    target_path = target_path.AppendASCII("testout_tilem.ppm");
+
+    ASSERT_TRUE(base::CopyFile(resource_path, target_path));
+
+    std::string prog_name = "tjbench";
+    std::string arg1 = target_path.MaybeAsASCII();
+    std::string arg2 = "95";
+    std::string arg3 = "-rgb";
+    std::string arg4 = "-fastupsample";
+    std::string arg5 = "-quiet";
+    std::string arg6 = "-tile";
+    std::string arg7 = "-benchtime";
+    std::string arg8 = "0.01";
+    std::string arg9 = "-warmup";
+    std::string arg10 = "0";
+    char *command_line[] = { &prog_name[0],
+                             &arg1[0], &arg2[0], &arg3[0], &arg4[0], &arg5[0],
+                             &arg6[0], &arg7[0], &arg8[0], &arg9[0], &arg10[0]
+                           };
+    // Generate test image output tiles.
+    EXPECT_EQ(tjbench(11, command_line), 0);
+  }
+
+};
+
+TEST_P(TJBenchTestMerged, TestTileMerged) {
+  // Construct path for test image file.
+  base::FilePath test_image_path(GetTargetDirectory());
+  test_image_path = test_image_path.AppendASCII(std::get<0>(GetParam()));
+  // Read test image as string and compute MD5 sum.
+  std::string test_image_data;
+  ASSERT_TRUE(base::ReadFileToString(test_image_path, &test_image_data));
+  const std::string md5 = base::MD5String(test_image_data);
+  // Compare expected MD5 sum against that of test image.
+  EXPECT_EQ(std::get<1>(GetParam()), md5);
+}
+
+INSTANTIATE_TEST_SUITE_P(TestTileMerged,
+                         TJBenchTestMerged,
+                         ::testing::ValuesIn(IMAGE_MD5_MERGED));
diff --git a/src/third_party/libjpeg-turbo/gtest/tjunittest-gtest-wrapper.cpp b/src/third_party/libjpeg-turbo/gtest/tjunittest-gtest-wrapper.cpp
new file mode 100644
index 0000000..bef4e94
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/gtest/tjunittest-gtest-wrapper.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2020 The Chromium Authors. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <gtest/gtest.h>
+
+extern "C" int testBmp(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByte444(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByte444(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByte422(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByte422(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByte420(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByte420(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByte440(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByte440(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByte411(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByte411(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testOnlyGray(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testThreeByteGray(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testFourByteGray(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testBufSize(int yuv, int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGB444(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGB422(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGB420(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGB440(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGB411(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyRGBGray(int noyuvpad, int autoalloc);
+extern "C" int testYUVOnlyGrayGray(int noyuvpad, int autoalloc);
+
+const int YUV = 1;
+const int NO_YUV = 0;
+const int NO_YUV_PAD = 1;
+const int YUV_PAD = 0;
+const int AUTO_ALLOC = 1;
+const int NO_AUTO_ALLOC = 0;
+
+class TJUnitTest : public
+  ::testing::TestWithParam<std::tuple<int, int, int>> {};
+
+TEST_P(TJUnitTest, BMP) {
+  EXPECT_EQ(testBmp(std::get<0>(GetParam()),
+                    std::get<1>(GetParam()),
+                    std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByte444) {
+  EXPECT_EQ(testThreeByte444(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByte444) {
+  EXPECT_EQ(testFourByte444(std::get<0>(GetParam()),
+                            std::get<1>(GetParam()),
+                            std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByte422) {
+  EXPECT_EQ(testThreeByte422(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByte422) {
+  EXPECT_EQ(testFourByte422(std::get<0>(GetParam()),
+                            std::get<1>(GetParam()),
+                            std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByte420) {
+  EXPECT_EQ(testThreeByte420(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByte420) {
+  EXPECT_EQ(testFourByte420(std::get<0>(GetParam()),
+                            std::get<1>(GetParam()),
+                            std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByte440) {
+  EXPECT_EQ(testThreeByte440(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByte440) {
+  EXPECT_EQ(testFourByte440(std::get<0>(GetParam()),
+                            std::get<1>(GetParam()),
+                            std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByte411) {
+  EXPECT_EQ(testThreeByte411(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByte411) {
+  EXPECT_EQ(testFourByte411(std::get<0>(GetParam()),
+                            std::get<1>(GetParam()),
+                            std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, OnlyGray) {
+  EXPECT_EQ(testOnlyGray(std::get<0>(GetParam()),
+                         std::get<1>(GetParam()),
+                         std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, ThreeByteGray) {
+  EXPECT_EQ(testThreeByteGray(std::get<0>(GetParam()),
+                              std::get<1>(GetParam()),
+                              std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, FourByteGray) {
+  EXPECT_EQ(testFourByteGray(std::get<0>(GetParam()),
+                             std::get<1>(GetParam()),
+                             std::get<2>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTest, BufSize) {
+  EXPECT_EQ(testBufSize(std::get<0>(GetParam()),
+                        std::get<1>(GetParam()),
+                        std::get<2>(GetParam())), 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        TJUnitTests,
+        TJUnitTest,
+        ::testing::Values(std::make_tuple(NO_YUV, YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(NO_YUV, YUV_PAD, AUTO_ALLOC),
+                          std::make_tuple(NO_YUV, NO_YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(NO_YUV, NO_YUV_PAD, AUTO_ALLOC),
+                          std::make_tuple(YUV, YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(YUV, YUV_PAD, AUTO_ALLOC),
+                          std::make_tuple(YUV, NO_YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(YUV, NO_YUV_PAD, AUTO_ALLOC)));
+
+class TJUnitTestYUV : public ::testing::TestWithParam<std::tuple<int, int>> {};
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGB444) {
+  EXPECT_EQ(testYUVOnlyRGB444(std::get<0>(GetParam()),
+                              std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGB422) {
+  EXPECT_EQ(testYUVOnlyRGB422(std::get<0>(GetParam()),
+                              std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGB420) {
+  EXPECT_EQ(testYUVOnlyRGB420(std::get<0>(GetParam()),
+                              std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGB440) {
+  EXPECT_EQ(testYUVOnlyRGB440(std::get<0>(GetParam()),
+                              std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGB411) {
+  EXPECT_EQ(testYUVOnlyRGB411(std::get<0>(GetParam()),
+                              std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyRGBGray) {
+  EXPECT_EQ(testYUVOnlyRGBGray(std::get<0>(GetParam()),
+                               std::get<1>(GetParam())), 0);
+}
+
+TEST_P(TJUnitTestYUV, YUVOnlyGrayGray) {
+  EXPECT_EQ(testYUVOnlyGrayGray(std::get<0>(GetParam()),
+                                std::get<1>(GetParam())), 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        TJUnitTestsYUV,
+        TJUnitTestYUV,
+        ::testing::Values(std::make_tuple(YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(YUV_PAD, AUTO_ALLOC),
+                          std::make_tuple(NO_YUV_PAD, NO_AUTO_ALLOC),
+                          std::make_tuple(NO_YUV_PAD, AUTO_ALLOC)));
diff --git a/src/third_party/libjpeg-turbo/jaricom.c b/src/third_party/libjpeg-turbo/jaricom.c
index 774be9e..215640c 100644
--- a/src/third_party/libjpeg-turbo/jaricom.c
+++ b/src/third_party/libjpeg-turbo/jaricom.c
@@ -4,16 +4,16 @@
  * This file was part of the Independent JPEG Group's software:
  * Developed 1997-2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015, D. R. Commander.
+ * Copyright (C) 2015, 2018, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
  * This file contains probability estimation tables for common use in
  * arithmetic entropy encoding and decoding routines.
  *
- * This data represents Table D.2 in the JPEG spec (ISO/IEC IS 10918-1
- * and CCITT Recommendation ITU-T T.81) and Table 24 in the JBIG spec
- * (ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82).
+ * This data represents Table D.2 in
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994 and Table 24 in
+ * Recommendation ITU-T T.82 (1993) | ISO/IEC 11544:1993.
  */
 
 #define JPEG_INTERNALS
diff --git a/src/third_party/libjpeg-turbo/java/CMakeLists.txt b/src/third_party/libjpeg-turbo/java/CMakeLists.txt
deleted file mode 100644
index d51ada7..0000000
--- a/src/third_party/libjpeg-turbo/java/CMakeLists.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-find_package(Java REQUIRED)
-find_package(JNI REQUIRED)
-
-# Allow the Java compiler flags to be set using an environment variable
-if(NOT DEFINED CMAKE_JAVA_COMPILE_FLAGS AND DEFINED ENV{JAVAFLAGS})
-  set(CMAKE_JAVA_COMPILE_FLAGS $ENV{JAVAFLAGS})
-endif()
-
-include(UseJava)
-
-set(CMAKE_JAVA_COMPILE_FLAGS "${CMAKE_JAVA_COMPILE_FLAGS} -J-Dfile.encoding=UTF8")
-message(STATUS "CMAKE_JAVA_COMPILE_FLAGS = ${CMAKE_JAVA_COMPILE_FLAGS}")
-string(REGEX REPLACE " " ";" CMAKE_JAVA_COMPILE_FLAGS "${CMAKE_JAVA_COMPILE_FLAGS}")
-
-set(JAVAARGS "" CACHE STRING "Additional arguments to pass to java when running unit tests (example: -d32)")
-message(STATUS "JAVAARGS = ${JAVAARGS}")
-
-set(JAVA_SOURCES org/libjpegturbo/turbojpeg/TJ.java
-  org/libjpegturbo/turbojpeg/TJCompressor.java
-  org/libjpegturbo/turbojpeg/TJCustomFilter.java
-  org/libjpegturbo/turbojpeg/TJDecompressor.java
-  org/libjpegturbo/turbojpeg/TJException.java
-  org/libjpegturbo/turbojpeg/TJScalingFactor.java
-  org/libjpegturbo/turbojpeg/TJTransform.java
-  org/libjpegturbo/turbojpeg/TJTransformer.java
-  org/libjpegturbo/turbojpeg/YUVImage.java
-  TJUnitTest.java
-  TJExample.java
-  TJBench.java)
-
-set(TURBOJPEG_DLL_NAME "turbojpeg")
-if(MINGW)
-  set(TURBOJPEG_DLL_NAME "libturbojpeg")
-endif()
-if(WIN32)
-  configure_file(org/libjpegturbo/turbojpeg/TJLoader-win.java.in
-    ${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
-else()
-  configure_file(org/libjpegturbo/turbojpeg/TJLoader-unix.java.in
-    ${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
-endif()
-set(JAVA_SOURCES ${JAVA_SOURCES}
-  ${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
-
-if(MSYS)
-  # UGLY HACK ALERT: If we don't do this, then UseJava.cmake will separate
-  # class path members with a semicolon, which is interpreted as a command
-  # separator by the MSYS shell.
-  set(CMAKE_HOST_SYSTEM_NAME_BAK ${CMAKE_HOST_SYSTEM_NAME})
-  set(CMAKE_HOST_SYSTEM_NAME "MSYS")
-endif()
-add_jar(turbojpeg-java ${JAVA_SOURCES} OUTPUT_NAME turbojpeg
-  ENTRY_POINT TJExample)
-if(MSYS)
-  set(CMAKE_HOST_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME_BAK})
-endif()
-
-add_custom_target(javadoc COMMAND
-  javadoc -notimestamp -d ${CMAKE_CURRENT_SOURCE_DIR}/doc -sourcepath ${CMAKE_CURRENT_SOURCE_DIR} org.libjpegturbo.turbojpeg)
-set(JAVACLASSPATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/turbojpeg-java.dir)
-add_custom_target(javah
-  COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJ
-  COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJCompressor
-  COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJDecompressor
-  COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJTransformer)
-
-if(NOT DEFINED CMAKE_INSTALL_DEFAULT_JAVADIR)
-  set(CMAKE_INSTALL_DEFAULT_JAVADIR "<CMAKE_INSTALL_DATAROOTDIR>/java")
-endif()
-GNUInstallDirs_set_install_dir(JAVADIR
-  "The directory into which Java classes should be installed")
-GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_JAVADIR
-  CMAKE_INSTALL_JAVADIR)
-set(CMAKE_INSTALL_JAVADIR ${CMAKE_INSTALL_JAVADIR} PARENT_SCOPE)
-set(CMAKE_INSTALL_FULL_JAVADIR ${CMAKE_INSTALL_FULL_JAVADIR} PARENT_SCOPE)
-report_directory(JAVADIR)
-install_jar(turbojpeg-java ${CMAKE_INSTALL_JAVADIR})
-mark_as_advanced(CLEAR CMAKE_INSTALL_JAVADIR)
diff --git a/src/third_party/libjpeg-turbo/java/MANIFEST.MF b/src/third_party/libjpeg-turbo/java/MANIFEST.MF
deleted file mode 100644
index 723bc51..0000000
--- a/src/third_party/libjpeg-turbo/java/MANIFEST.MF
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: TJExample
diff --git a/src/third_party/libjpeg-turbo/java/README b/src/third_party/libjpeg-turbo/java/README
deleted file mode 100644
index 88ddc3b..0000000
--- a/src/third_party/libjpeg-turbo/java/README
+++ /dev/null
@@ -1,52 +0,0 @@
-TurboJPEG Java Wrapper
-======================
-
-The TurboJPEG shared library can optionally be built with a Java Native
-Interface wrapper, which allows the library to be loaded and used directly from
-Java applications.  The Java front end for this is defined in several classes
-located under org/libjpegturbo/turbojpeg.  The source code for these Java
-classes is licensed under a BSD-style license, so the files can be incorporated
-directly into both open source and proprietary projects without restriction.  A
-Java archive (JAR) file containing these classes is also shipped with the
-"official" distribution packages of libjpeg-turbo.
-
-TJExample.java, which should also be located in the same directory as this
-README file, demonstrates how to use the TurboJPEG Java API to compress and
-decompress JPEG images in memory.
-
-
-Performance Pitfalls
---------------------
-
-The TurboJPEG Java API defines several convenience methods that can allocate
-image buffers or instantiate classes to hold the result of compress,
-decompress, or transform operations.  However, if you use these methods, then
-be mindful of the amount of new data you are creating on the heap.  It may be
-necessary to manually invoke the garbage collector to prevent heap exhaustion
-or to prevent performance degradation.  Background garbage collection can kill
-performance, particularly in a multi-threaded environment (Java pauses all
-threads when the GC runs.)
-
-The TurboJPEG Java API always gives you the option of pre-allocating your own
-source and destination buffers, which allows you to re-use those buffers for
-compressing/decompressing multiple images.  If the image sequence you are
-compressing or decompressing consists of images of the same size, then
-pre-allocating the buffers is recommended.
-
-
-Installation Directory
-----------------------
-
-The TurboJPEG Java Wrapper will look for the TurboJPEG JNI library
-(libturbojpeg.so, libturbojpeg.jnilib, or turbojpeg.dll) in the system library
-paths or in any paths specified in LD_LIBRARY_PATH (Un*x), DYLD_LIBRARY_PATH
-(Mac), or PATH (Windows.)  Failing this, on Un*x and Mac systems, the wrapper
-will look for the JNI library under the library directory configured when
-libjpeg-turbo was built.  If that library directory is
-/opt/libjpeg-turbo/lib32, then /opt/libjpeg-turbo/lib64 is also searched, and
-vice versa.
-
-If you installed the JNI library into another directory, then you will need
-to pass an argument of -Djava.library.path={path_to_JNI_library} to java, or
-manipulate LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, or PATH to include the directory
-containing the JNI library.
diff --git a/src/third_party/libjpeg-turbo/java/TJBench.java b/src/third_party/libjpeg-turbo/java/TJBench.java
deleted file mode 100644
index bd55562..0000000
--- a/src/third_party/libjpeg-turbo/java/TJBench.java
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * Copyright (C)2009-2014, 2016-2018 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-import java.io.*;
-import java.awt.image.*;
-import javax.imageio.*;
-import java.util.*;
-import org.libjpegturbo.turbojpeg.*;
-
-final class TJBench {
-
-  private TJBench() {}
-
-  private static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvPad = 1;
-  private static boolean compOnly, decompOnly, doTile, doYUV, write = true;
-
-  static final String[] PIXFORMATSTR = {
-    "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
-  };
-
-  static final String[] SUBNAME_LONG = {
-    "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
-  };
-
-  static final String[] SUBNAME = {
-    "444", "422", "420", "GRAY", "440", "411"
-  };
-
-  static final String[] CSNAME = {
-    "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
-  };
-
-  private static TJScalingFactor sf;
-  private static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
-  private static double benchTime = 5.0, warmup = 1.0;
-
-
-  static double getTime() {
-    return (double)System.nanoTime() / 1.0e9;
-  }
-
-
-  private static String tjErrorMsg;
-  private static int tjErrorCode = -1;
-
-  static void handleTJException(TJException e) throws TJException {
-    String errorMsg = e.getMessage();
-    int errorCode = e.getErrorCode();
-
-    if ((flags & TJ.FLAG_STOPONWARNING) == 0 &&
-        errorCode == TJ.ERR_WARNING) {
-      if (tjErrorMsg == null || !tjErrorMsg.equals(errorMsg) ||
-          tjErrorCode != errorCode) {
-        tjErrorMsg = errorMsg;
-        tjErrorCode = errorCode;
-        System.out.println("WARNING: " + errorMsg);
-      }
-    } else
-      throw e;
-  }
-
-
-  static String formatName(int subsamp, int cs) {
-    if (cs == TJ.CS_YCbCr)
-      return SUBNAME_LONG[subsamp];
-    else if (cs == TJ.CS_YCCK)
-      return CSNAME[cs] + " " + SUBNAME_LONG[subsamp];
-    else
-      return CSNAME[cs];
-  }
-
-
-  static String sigFig(double val, int figs) {
-    String format;
-    int digitsAfterDecimal = figs - (int)Math.ceil(Math.log10(Math.abs(val)));
-
-    if (digitsAfterDecimal < 1)
-      format = new String("%.0f");
-    else
-      format = new String("%." + digitsAfterDecimal + "f");
-    return String.format(format, val);
-  }
-
-
-  static byte[] loadImage(String fileName, int[] w, int[] h, int pixelFormat)
-                          throws Exception {
-    BufferedImage img = ImageIO.read(new File(fileName));
-
-    if (img == null)
-      throw new Exception("Could not read " + fileName);
-    w[0] = img.getWidth();
-    h[0] = img.getHeight();
-
-    int[] rgb = img.getRGB(0, 0, w[0], h[0], null, 0, w[0]);
-    int ps = TJ.getPixelSize(pixelFormat);
-    int rindex = TJ.getRedOffset(pixelFormat);
-    int gindex = TJ.getGreenOffset(pixelFormat);
-    int bindex = TJ.getBlueOffset(pixelFormat);
-    byte[] dstBuf = new byte[w[0] * h[0] * ps];
-    int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
-
-    while (pixels-- > 0) {
-      dstBuf[dstPtr + rindex] = (byte)((rgb[rgbPtr] >> 16) & 0xff);
-      dstBuf[dstPtr + gindex] = (byte)((rgb[rgbPtr] >> 8) & 0xff);
-      dstBuf[dstPtr + bindex] = (byte)(rgb[rgbPtr] & 0xff);
-      dstPtr += ps;
-      rgbPtr++;
-    }
-    return dstBuf;
-  }
-
-
-  static void saveImage(String fileName, byte[] srcBuf, int w, int h,
-                        int pixelFormat) throws Exception {
-    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
-    int pixels = w * h, srcPtr = 0;
-    int ps = TJ.getPixelSize(pixelFormat);
-    int rindex = TJ.getRedOffset(pixelFormat);
-    int gindex = TJ.getGreenOffset(pixelFormat);
-    int bindex = TJ.getBlueOffset(pixelFormat);
-
-    for (int y = 0; y < h; y++) {
-      for (int x = 0; x < w; x++, srcPtr += ps) {
-        int pixel = (srcBuf[srcPtr + rindex] & 0xff) << 16 |
-                    (srcBuf[srcPtr + gindex] & 0xff) << 8 |
-                    (srcBuf[srcPtr + bindex] & 0xff);
-
-        img.setRGB(x, y, pixel);
-      }
-    }
-    ImageIO.write(img, "bmp", new File(fileName));
-  }
-
-
-  /* Decompression test */
-  static void decomp(byte[] srcBuf, byte[][] jpegBuf, int[] jpegSize,
-                     byte[] dstBuf, int w, int h, int subsamp, int jpegQual,
-                     String fileName, int tilew, int tileh) throws Exception {
-    String qualStr = new String(""), sizeStr, tempStr;
-    TJDecompressor tjd;
-    double elapsed, elapsedDecode;
-    int ps = TJ.getPixelSize(pf), i, iter = 0;
-    int scaledw = sf.getScaled(w);
-    int scaledh = sf.getScaled(h);
-    int pitch = scaledw * ps;
-    YUVImage yuvImage = null;
-
-    if (jpegQual > 0)
-      qualStr = new String("_Q" + jpegQual);
-
-    tjd = new TJDecompressor();
-
-    if (dstBuf == null)
-      dstBuf = new byte[pitch * scaledh];
-
-    /* Set the destination buffer to gray so we know whether the decompressor
-       attempted to write to it */
-    Arrays.fill(dstBuf, (byte)127);
-
-    if (doYUV) {
-      int width = doTile ? tilew : scaledw;
-      int height = doTile ? tileh : scaledh;
-
-      yuvImage = new YUVImage(width, yuvPad, height, subsamp);
-      Arrays.fill(yuvImage.getBuf(), (byte)127);
-    }
-
-    /* Benchmark */
-    iter = -1;
-    elapsed = elapsedDecode = 0.0;
-    while (true) {
-      int tile = 0;
-      double start = getTime();
-
-      for (int y = 0; y < h; y += tileh) {
-        for (int x = 0; x < w; x += tilew, tile++) {
-          int width = doTile ? Math.min(tilew, w - x) : scaledw;
-          int height = doTile ? Math.min(tileh, h - y) : scaledh;
-
-          tjd.setSourceImage(jpegBuf[tile], jpegSize[tile]);
-          if (doYUV) {
-            yuvImage.setBuf(yuvImage.getBuf(), width, yuvPad, height, subsamp);
-            try {
-              tjd.decompressToYUV(yuvImage, flags);
-            } catch (TJException e) { handleTJException(e); }
-            double startDecode = getTime();
-            tjd.setSourceImage(yuvImage);
-            try {
-              tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
-            } catch (TJException e) { handleTJException(e); }
-            if (iter >= 0)
-              elapsedDecode += getTime() - startDecode;
-          } else {
-            try {
-              tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
-            } catch (TJException e) { handleTJException(e); }
-          }
-        }
-      }
-      elapsed += getTime() - start;
-      if (iter >= 0) {
-        iter++;
-        if (elapsed >= benchTime)
-          break;
-      } else if (elapsed >= warmup) {
-        iter = 0;
-        elapsed = elapsedDecode = 0.0;
-      }
-    }
-    if (doYUV)
-      elapsed -= elapsedDecode;
-
-    tjd = null;
-    for (i = 0; i < jpegBuf.length; i++)
-      jpegBuf[i] = null;
-    jpegBuf = null;  jpegSize = null;
-    System.gc();
-
-    if (quiet != 0) {
-      System.out.format("%-6s%s",
-                        sigFig((double)(w * h) / 1000000. *
-                               (double)iter / elapsed, 4),
-                        quiet == 2 ? "\n" : "  ");
-      if (doYUV)
-        System.out.format("%s\n",
-                          sigFig((double)(w * h) / 1000000. *
-                                 (double)iter / elapsedDecode, 4));
-      else if (quiet != 2)
-        System.out.print("\n");
-    } else {
-      System.out.format("%s --> Frame rate:         %f fps\n",
-                        (doYUV ? "Decomp to YUV" : "Decompress   "),
-                        (double)iter / elapsed);
-      System.out.format("                  Throughput:         %f Megapixels/sec\n",
-                        (double)(w * h) / 1000000. * (double)iter / elapsed);
-      if (doYUV) {
-        System.out.format("YUV Decode    --> Frame rate:         %f fps\n",
-                          (double)iter / elapsedDecode);
-        System.out.format("                  Throughput:         %f Megapixels/sec\n",
-                          (double)(w * h) / 1000000. *
-                          (double)iter / elapsedDecode);
-      }
-    }
-
-    if (!write) return;
-
-    if (sf.getNum() != 1 || sf.getDenom() != 1)
-      sizeStr = new String(sf.getNum() + "_" + sf.getDenom());
-    else if (tilew != w || tileh != h)
-      sizeStr = new String(tilew + "x" + tileh);
-    else
-      sizeStr = new String("full");
-    if (decompOnly)
-      tempStr = new String(fileName + "_" + sizeStr + ".bmp");
-    else
-      tempStr = new String(fileName + "_" + SUBNAME[subsamp] + qualStr +
-                           "_" + sizeStr + ".bmp");
-
-    saveImage(tempStr, dstBuf, scaledw, scaledh, pf);
-    int ndx = tempStr.lastIndexOf('.');
-    tempStr = new String(tempStr.substring(0, ndx) + "-err.bmp");
-    if (srcBuf != null && sf.getNum() == 1 && sf.getDenom() == 1) {
-      if (quiet == 0)
-        System.out.println("Compression error written to " + tempStr + ".");
-      if (subsamp == TJ.SAMP_GRAY) {
-        for (int y = 0, index = 0; y < h; y++, index += pitch) {
-          for (int x = 0, index2 = index; x < w; x++, index2 += ps) {
-            int rindex = index2 + TJ.getRedOffset(pf);
-            int gindex = index2 + TJ.getGreenOffset(pf);
-            int bindex = index2 + TJ.getBlueOffset(pf);
-            int lum = (int)((double)(srcBuf[rindex] & 0xff) * 0.299 +
-                            (double)(srcBuf[gindex] & 0xff) * 0.587 +
-                            (double)(srcBuf[bindex] & 0xff) * 0.114 + 0.5);
-
-            if (lum > 255) lum = 255;
-            if (lum < 0) lum = 0;
-            dstBuf[rindex] = (byte)Math.abs((dstBuf[rindex] & 0xff) - lum);
-            dstBuf[gindex] = (byte)Math.abs((dstBuf[gindex] & 0xff) - lum);
-            dstBuf[bindex] = (byte)Math.abs((dstBuf[bindex] & 0xff) - lum);
-          }
-        }
-      } else {
-        for (int y = 0; y < h; y++)
-          for (int x = 0; x < w * ps; x++)
-            dstBuf[pitch * y + x] =
-              (byte)Math.abs((dstBuf[pitch * y + x] & 0xff) -
-                             (srcBuf[pitch * y + x] & 0xff));
-      }
-      saveImage(tempStr, dstBuf, w, h, pf);
-    }
-  }
-
-
-  static void fullTest(byte[] srcBuf, int w, int h, int subsamp, int jpegQual,
-                       String fileName) throws Exception {
-    TJCompressor tjc;
-    byte[] tmpBuf;
-    byte[][] jpegBuf;
-    int[] jpegSize;
-    double start, elapsed, elapsedEncode;
-    int totalJpegSize = 0, tilew, tileh, i, iter;
-    int ps = TJ.getPixelSize(pf);
-    int ntilesw = 1, ntilesh = 1, pitch = w * ps;
-    String pfStr = PIXFORMATSTR[pf];
-    YUVImage yuvImage = null;
-
-    tmpBuf = new byte[pitch * h];
-
-    if (quiet == 0)
-      System.out.format(">>>>>  %s (%s) <--> JPEG %s Q%d  <<<<<\n", pfStr,
-                        (flags & TJ.FLAG_BOTTOMUP) != 0 ?
-                        "Bottom-up" : "Top-down",
-                        SUBNAME_LONG[subsamp], jpegQual);
-
-    tjc = new TJCompressor();
-
-    for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ;
-         tilew *= 2, tileh *= 2) {
-      if (tilew > w)
-        tilew = w;
-      if (tileh > h)
-        tileh = h;
-      ntilesw = (w + tilew - 1) / tilew;
-      ntilesh = (h + tileh - 1) / tileh;
-
-      jpegBuf = new byte[ntilesw * ntilesh][TJ.bufSize(tilew, tileh, subsamp)];
-      jpegSize = new int[ntilesw * ntilesh];
-
-      /* Compression test */
-      if (quiet == 1)
-        System.out.format("%-4s (%s)  %-5s    %-3d   ", pfStr,
-                          (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
-                          SUBNAME_LONG[subsamp], jpegQual);
-      for (i = 0; i < h; i++)
-        System.arraycopy(srcBuf, w * ps * i, tmpBuf, pitch * i, w * ps);
-      tjc.setJPEGQuality(jpegQual);
-      tjc.setSubsamp(subsamp);
-
-      if (doYUV) {
-        yuvImage = new YUVImage(tilew, yuvPad, tileh, subsamp);
-        Arrays.fill(yuvImage.getBuf(), (byte)127);
-      }
-
-      /* Benchmark */
-      iter = -1;
-      elapsed = elapsedEncode = 0.0;
-      while (true) {
-        int tile = 0;
-
-        totalJpegSize = 0;
-        start = getTime();
-        for (int y = 0; y < h; y += tileh) {
-          for (int x = 0; x < w; x += tilew, tile++) {
-            int width = Math.min(tilew, w - x);
-            int height = Math.min(tileh, h - y);
-
-            tjc.setSourceImage(srcBuf, x, y, width, pitch, height, pf);
-            if (doYUV) {
-              double startEncode = getTime();
-
-              yuvImage.setBuf(yuvImage.getBuf(), width, yuvPad, height,
-                              subsamp);
-              tjc.encodeYUV(yuvImage, flags);
-              if (iter >= 0)
-                elapsedEncode += getTime() - startEncode;
-              tjc.setSourceImage(yuvImage);
-            }
-            tjc.compress(jpegBuf[tile], flags);
-            jpegSize[tile] = tjc.getCompressedSize();
-            totalJpegSize += jpegSize[tile];
-          }
-        }
-        elapsed += getTime() - start;
-        if (iter >= 0) {
-          iter++;
-          if (elapsed >= benchTime)
-            break;
-        } else if (elapsed >= warmup) {
-          iter = 0;
-          elapsed = elapsedEncode = 0.0;
-        }
-      }
-      if (doYUV)
-        elapsed -= elapsedEncode;
-
-      if (quiet == 1)
-        System.out.format("%-5d  %-5d   ", tilew, tileh);
-      if (quiet != 0) {
-        if (doYUV)
-          System.out.format("%-6s%s",
-                            sigFig((double)(w * h) / 1000000. *
-                                   (double)iter / elapsedEncode, 4),
-                            quiet == 2 ? "\n" : "  ");
-        System.out.format("%-6s%s",
-                          sigFig((double)(w * h) / 1000000. *
-                                 (double)iter / elapsed, 4),
-                          quiet == 2 ? "\n" : "  ");
-        System.out.format("%-6s%s",
-                          sigFig((double)(w * h * ps) / (double)totalJpegSize,
-                                 4),
-                          quiet == 2 ? "\n" : "  ");
-      } else {
-        System.out.format("\n%s size: %d x %d\n", doTile ? "Tile" : "Image",
-                          tilew, tileh);
-        if (doYUV) {
-          System.out.format("Encode YUV    --> Frame rate:         %f fps\n",
-                            (double)iter / elapsedEncode);
-          System.out.format("                  Output image size:  %d bytes\n",
-                            yuvImage.getSize());
-          System.out.format("                  Compression ratio:  %f:1\n",
-                            (double)(w * h * ps) / (double)yuvImage.getSize());
-          System.out.format("                  Throughput:         %f Megapixels/sec\n",
-                            (double)(w * h) / 1000000. *
-                            (double)iter / elapsedEncode);
-          System.out.format("                  Output bit stream:  %f Megabits/sec\n",
-                            (double)yuvImage.getSize() * 8. / 1000000. *
-                            (double)iter / elapsedEncode);
-        }
-        System.out.format("%s --> Frame rate:         %f fps\n",
-                          doYUV ? "Comp from YUV" : "Compress     ",
-                          (double)iter / elapsed);
-        System.out.format("                  Output image size:  %d bytes\n",
-                          totalJpegSize);
-        System.out.format("                  Compression ratio:  %f:1\n",
-                          (double)(w * h * ps) / (double)totalJpegSize);
-        System.out.format("                  Throughput:         %f Megapixels/sec\n",
-                          (double)(w * h) / 1000000. * (double)iter / elapsed);
-        System.out.format("                  Output bit stream:  %f Megabits/sec\n",
-                          (double)totalJpegSize * 8. / 1000000. *
-                          (double)iter / elapsed);
-      }
-      if (tilew == w && tileh == h && write) {
-        String tempStr = fileName + "_" + SUBNAME[subsamp] + "_" + "Q" +
-                         jpegQual + ".jpg";
-        FileOutputStream fos = new FileOutputStream(tempStr);
-
-        fos.write(jpegBuf[0], 0, jpegSize[0]);
-        fos.close();
-        if (quiet == 0)
-          System.out.println("Reference image written to " + tempStr);
-      }
-
-      /* Decompression test */
-      if (!compOnly)
-        decomp(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual,
-               fileName, tilew, tileh);
-
-      if (tilew == w && tileh == h) break;
-    }
-  }
-
-
-  static void decompTest(String fileName) throws Exception {
-    TJTransformer tjt;
-    byte[][] jpegBuf = null;
-    byte[] srcBuf;
-    int[] jpegSize = null;
-    int totalJpegSize;
-    double start, elapsed;
-    int ps = TJ.getPixelSize(pf), tile, x, y, iter;
-    // Original image
-    int w = 0, h = 0, ntilesw = 1, ntilesh = 1, subsamp = -1, cs = -1;
-    // Transformed image
-    int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
-
-    FileInputStream fis = new FileInputStream(fileName);
-    int srcSize = (int)fis.getChannel().size();
-    srcBuf = new byte[srcSize];
-    fis.read(srcBuf, 0, srcSize);
-    fis.close();
-
-    int index = fileName.lastIndexOf('.');
-    if (index >= 0)
-      fileName = new String(fileName.substring(0, index));
-
-    tjt = new TJTransformer();
-
-    tjt.setSourceImage(srcBuf, srcSize);
-    w = tjt.getWidth();
-    h = tjt.getHeight();
-    subsamp = tjt.getSubsamp();
-    cs = tjt.getColorspace();
-
-    if (quiet == 1) {
-      System.out.println("All performance values in Mpixels/sec\n");
-      System.out.format("Bitmap     JPEG   JPEG     %s  %s   Xform   Comp    Decomp  ",
-                        (doTile ? "Tile " : "Image"),
-                        (doTile ? "Tile " : "Image"));
-      if (doYUV)
-        System.out.print("Decode");
-      System.out.print("\n");
-      System.out.print("Format     CS     Subsamp  Width  Height  Perf    Ratio   Perf    ");
-      if (doYUV)
-        System.out.print("Perf");
-      System.out.println("\n");
-    } else if (quiet == 0)
-      System.out.format(">>>>>  JPEG %s --> %s (%s)  <<<<<\n",
-                        formatName(subsamp, cs), PIXFORMATSTR[pf],
-                        (flags & TJ.FLAG_BOTTOMUP) != 0 ?
-                        "Bottom-up" : "Top-down");
-
-    for (int tilew = doTile ? 16 : w, tileh = doTile ? 16 : h; ;
-         tilew *= 2, tileh *= 2) {
-      if (tilew > w)
-        tilew = w;
-      if (tileh > h)
-        tileh = h;
-      ntilesw = (w + tilew - 1) / tilew;
-      ntilesh = (h + tileh - 1) / tileh;
-
-      tw = w;  th = h;  ttilew = tilew;  ttileh = tileh;
-      if (quiet == 0) {
-        System.out.format("\n%s size: %d x %d", (doTile ? "Tile" : "Image"),
-                          ttilew, ttileh);
-        if (sf.getNum() != 1 || sf.getDenom() != 1)
-          System.out.format(" --> %d x %d", sf.getScaled(tw),
-                            sf.getScaled(th));
-        System.out.println("");
-      } else if (quiet == 1) {
-        System.out.format("%-4s (%s)  %-5s  %-5s    ", PIXFORMATSTR[pf],
-                          (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
-                          CSNAME[cs], SUBNAME_LONG[subsamp]);
-        System.out.format("%-5d  %-5d   ", tilew, tileh);
-      }
-
-      tsubsamp = subsamp;
-      if (doTile || xformOp != TJTransform.OP_NONE || xformOpt != 0) {
-        if (xformOp == TJTransform.OP_TRANSPOSE ||
-            xformOp == TJTransform.OP_TRANSVERSE ||
-            xformOp == TJTransform.OP_ROT90 ||
-            xformOp == TJTransform.OP_ROT270) {
-          tw = h;  th = w;  ttilew = tileh;  ttileh = tilew;
-        }
-
-        if ((xformOpt & TJTransform.OPT_GRAY) != 0)
-          tsubsamp = TJ.SAMP_GRAY;
-        if (xformOp == TJTransform.OP_HFLIP ||
-            xformOp == TJTransform.OP_ROT180)
-          tw = tw - (tw % TJ.getMCUWidth(tsubsamp));
-        if (xformOp == TJTransform.OP_VFLIP ||
-            xformOp == TJTransform.OP_ROT180)
-          th = th - (th % TJ.getMCUHeight(tsubsamp));
-        if (xformOp == TJTransform.OP_TRANSVERSE ||
-            xformOp == TJTransform.OP_ROT90)
-          tw = tw - (tw % TJ.getMCUHeight(tsubsamp));
-        if (xformOp == TJTransform.OP_TRANSVERSE ||
-            xformOp == TJTransform.OP_ROT270)
-          th = th - (th % TJ.getMCUWidth(tsubsamp));
-        tntilesw = (tw + ttilew - 1) / ttilew;
-        tntilesh = (th + ttileh - 1) / ttileh;
-
-        if (xformOp == TJTransform.OP_TRANSPOSE ||
-            xformOp == TJTransform.OP_TRANSVERSE ||
-            xformOp == TJTransform.OP_ROT90 ||
-            xformOp == TJTransform.OP_ROT270) {
-          if (tsubsamp == TJ.SAMP_422)
-            tsubsamp = TJ.SAMP_440;
-          else if (tsubsamp == TJ.SAMP_440)
-            tsubsamp = TJ.SAMP_422;
-        }
-
-        TJTransform[] t = new TJTransform[tntilesw * tntilesh];
-        jpegBuf =
-          new byte[tntilesw * tntilesh][TJ.bufSize(ttilew, ttileh, subsamp)];
-
-        for (y = 0, tile = 0; y < th; y += ttileh) {
-          for (x = 0; x < tw; x += ttilew, tile++) {
-            t[tile] = new TJTransform();
-            t[tile].width = Math.min(ttilew, tw - x);
-            t[tile].height = Math.min(ttileh, th - y);
-            t[tile].x = x;
-            t[tile].y = y;
-            t[tile].op = xformOp;
-            t[tile].options = xformOpt | TJTransform.OPT_TRIM;
-            if ((t[tile].options & TJTransform.OPT_NOOUTPUT) != 0 &&
-                jpegBuf[tile] != null)
-              jpegBuf[tile] = null;
-          }
-        }
-
-        iter = -1;
-        elapsed = 0.;
-        while (true) {
-          start = getTime();
-          tjt.transform(jpegBuf, t, flags);
-          jpegSize = tjt.getTransformedSizes();
-          elapsed += getTime() - start;
-          if (iter >= 0) {
-            iter++;
-            if (elapsed >= benchTime)
-              break;
-          } else if (elapsed >= warmup) {
-            iter = 0;
-            elapsed = 0.0;
-          }
-        }
-        t = null;
-
-        for (tile = 0, totalJpegSize = 0; tile < tntilesw * tntilesh; tile++)
-          totalJpegSize += jpegSize[tile];
-
-        if (quiet != 0) {
-          System.out.format("%-6s%s%-6s%s",
-                            sigFig((double)(w * h) / 1000000. / elapsed, 4),
-                            quiet == 2 ? "\n" : "  ",
-                            sigFig((double)(w * h * ps) /
-                                   (double)totalJpegSize, 4),
-                            quiet == 2 ? "\n" : "  ");
-        } else if (quiet == 0) {
-          System.out.format("Transform     --> Frame rate:         %f fps\n",
-                            1.0 / elapsed);
-          System.out.format("                  Output image size:  %d bytes\n",
-                            totalJpegSize);
-          System.out.format("                  Compression ratio:  %f:1\n",
-                            (double)(w * h * ps) / (double)totalJpegSize);
-          System.out.format("                  Throughput:         %f Megapixels/sec\n",
-                            (double)(w * h) / 1000000. / elapsed);
-          System.out.format("                  Output bit stream:  %f Megabits/sec\n",
-                            (double)totalJpegSize * 8. / 1000000. / elapsed);
-        }
-      } else {
-        if (quiet == 1)
-          System.out.print("N/A     N/A     ");
-        jpegBuf = new byte[1][TJ.bufSize(ttilew, ttileh, subsamp)];
-        jpegSize = new int[1];
-        jpegBuf[0] = srcBuf;
-        jpegSize[0] = srcSize;
-      }
-
-      if (w == tilew)
-        ttilew = tw;
-      if (h == tileh)
-        ttileh = th;
-      if ((xformOpt & TJTransform.OPT_NOOUTPUT) == 0)
-        decomp(null, jpegBuf, jpegSize, null, tw, th, tsubsamp, 0,
-               fileName, ttilew, ttileh);
-      else if (quiet == 1)
-        System.out.println("N/A");
-
-      jpegBuf = null;
-      jpegSize = null;
-
-      if (tilew == w && tileh == h) break;
-    }
-  }
-
-
-  static void usage() throws Exception {
-    int i;
-    TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
-    int nsf = scalingFactors.length;
-    String className = new TJBench().getClass().getName();
-
-    System.out.println("\nUSAGE: java " + className);
-    System.out.println("       <Inputfile (BMP)> <Quality> [options]\n");
-    System.out.println("       java " + className);
-    System.out.println("       <Inputfile (JPG)> [options]\n");
-    System.out.println("Options:\n");
-    System.out.println("-alloc = Dynamically allocate JPEG image buffers");
-    System.out.println("-bottomup = Test bottom-up compression/decompression");
-    System.out.println("-tile = Test performance of the codec when the image is encoded as separate");
-    System.out.println("     tiles of varying sizes.");
-    System.out.println("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =");
-    System.out.println("     Test the specified color conversion path in the codec (default = BGR)");
-    System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available in");
-    System.out.println("     the underlying codec");
-    System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
-    System.out.println("     codec");
-    System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the");
-    System.out.println("     underlying codec");
-    System.out.println("-progressive = Use progressive entropy coding in JPEG images generated by");
-    System.out.println("     compression and transform operations.");
-    System.out.println("-subsamp <s> = When testing JPEG compression, this option specifies the level");
-    System.out.println("     of chrominance subsampling to use (<s> = 444, 422, 440, 420, 411, or");
-    System.out.println("     GRAY).  The default is to test Grayscale, 4:2:0, 4:2:2, and 4:4:4 in");
-    System.out.println("     sequence.");
-    System.out.println("-quiet = Output results in tabular rather than verbose format");
-    System.out.println("-yuv = Test YUV encoding/decoding functions");
-    System.out.println("-yuvpad <p> = If testing YUV encoding/decoding, this specifies the number of");
-    System.out.println("     bytes to which each row of each plane in the intermediate YUV image is");
-    System.out.println("     padded (default = 1)");
-    System.out.println("-scale M/N = Scale down the width/height of the decompressed JPEG image by a");
-    System.out.print  ("     factor of M/N (M/N = ");
-    for (i = 0; i < nsf; i++) {
-      System.out.format("%d/%d", scalingFactors[i].getNum(),
-                        scalingFactors[i].getDenom());
-      if (nsf == 2 && i != nsf - 1)
-        System.out.print(" or ");
-      else if (nsf > 2) {
-        if (i != nsf - 1)
-          System.out.print(", ");
-        if (i == nsf - 2)
-          System.out.print("or ");
-      }
-      if (i % 8 == 0 && i != 0)
-        System.out.print("\n     ");
-    }
-    System.out.println(")");
-    System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
-    System.out.println("     Perform the corresponding lossless transform prior to");
-    System.out.println("     decompression (these options are mutually exclusive)");
-    System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression");
-    System.out.println("     test (can be combined with the other transforms above)");
-    System.out.println("-copynone = Do not copy any extra markers (including EXIF and ICC profile data)");
-    System.out.println("     when transforming the image.");
-    System.out.println("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)");
-    System.out.println("-warmup <t> = Run each benchmark for <t> seconds (default = 1.0) prior to");
-    System.out.println("     starting the timer, in order to prime the caches and thus improve the");
-    System.out.println("     consistency of the results.");
-    System.out.println("-componly = Stop after running compression tests.  Do not test decompression.");
-    System.out.println("-nowrite = Do not write reference or output images (improves consistency");
-    System.out.println("     of performance measurements.)");
-    System.out.println("-stoponwarning = Immediately discontinue the current");
-    System.out.println("     compression/decompression/transform operation if the underlying codec");
-    System.out.println("     throws a warning (non-fatal error)\n");
-    System.out.println("NOTE:  If the quality is specified as a range (e.g. 90-100), a separate");
-    System.out.println("test will be performed for all quality values in the range.\n");
-    System.exit(1);
-  }
-
-
-  public static void main(String[] argv) {
-    byte[] srcBuf = null;
-    int w = 0, h = 0, minQual = -1, maxQual = -1;
-    int minArg = 1, retval = 0;
-    int subsamp = -1;
-
-    try {
-
-      if (argv.length < minArg)
-        usage();
-
-      String tempStr = argv[0].toLowerCase();
-      if (tempStr.endsWith(".jpg") || tempStr.endsWith(".jpeg"))
-        decompOnly = true;
-
-      System.out.println("");
-
-      if (!decompOnly) {
-        minArg = 2;
-        if (argv.length < minArg)
-          usage();
-        try {
-          minQual = Integer.parseInt(argv[1]);
-        } catch (NumberFormatException e) {}
-        if (minQual < 1 || minQual > 100)
-          throw new Exception("Quality must be between 1 and 100.");
-        int dashIndex = argv[1].indexOf('-');
-        if (dashIndex > 0 && argv[1].length() > dashIndex + 1) {
-          try {
-            maxQual = Integer.parseInt(argv[1].substring(dashIndex + 1));
-          } catch (NumberFormatException e) {}
-        }
-        if (maxQual < 1 || maxQual > 100)
-          maxQual = minQual;
-      }
-
-      if (argv.length > minArg) {
-        for (int i = minArg; i < argv.length; i++) {
-          if (argv[i].equalsIgnoreCase("-tile")) {
-            doTile = true;  xformOpt |= TJTransform.OPT_CROP;
-          } else if (argv[i].equalsIgnoreCase("-fastupsample")) {
-            System.out.println("Using fast upsampling code\n");
-            flags |= TJ.FLAG_FASTUPSAMPLE;
-          } else if (argv[i].equalsIgnoreCase("-fastdct")) {
-            System.out.println("Using fastest DCT/IDCT algorithm\n");
-            flags |= TJ.FLAG_FASTDCT;
-          } else if (argv[i].equalsIgnoreCase("-accuratedct")) {
-            System.out.println("Using most accurate DCT/IDCT algorithm\n");
-            flags |= TJ.FLAG_ACCURATEDCT;
-          } else if (argv[i].equalsIgnoreCase("-progressive")) {
-            System.out.println("Using progressive entropy coding\n");
-            flags |= TJ.FLAG_PROGRESSIVE;
-          } else if (argv[i].equalsIgnoreCase("-rgb"))
-            pf = TJ.PF_RGB;
-          else if (argv[i].equalsIgnoreCase("-rgbx"))
-            pf = TJ.PF_RGBX;
-          else if (argv[i].equalsIgnoreCase("-bgr"))
-            pf = TJ.PF_BGR;
-          else if (argv[i].equalsIgnoreCase("-bgrx"))
-            pf = TJ.PF_BGRX;
-          else if (argv[i].equalsIgnoreCase("-xbgr"))
-            pf = TJ.PF_XBGR;
-          else if (argv[i].equalsIgnoreCase("-xrgb"))
-            pf = TJ.PF_XRGB;
-          else if (argv[i].equalsIgnoreCase("-bottomup"))
-            flags |= TJ.FLAG_BOTTOMUP;
-          else if (argv[i].equalsIgnoreCase("-quiet"))
-            quiet = 1;
-          else if (argv[i].equalsIgnoreCase("-qq"))
-            quiet = 2;
-          else if (argv[i].equalsIgnoreCase("-scale") && i < argv.length - 1) {
-            int temp1 = 0, temp2 = 0;
-            boolean match = false, scanned = true;
-            Scanner scanner = new Scanner(argv[++i]).useDelimiter("/");
-
-            try {
-              temp1 = scanner.nextInt();
-              temp2 = scanner.nextInt();
-            } catch (Exception e) {}
-            if (temp2 <= 0) temp2 = 1;
-            if (temp1 > 0) {
-              TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
-
-              for (int j = 0; j < scalingFactors.length; j++) {
-                if ((double)temp1 / (double)temp2 ==
-                    (double)scalingFactors[j].getNum() /
-                    (double)scalingFactors[j].getDenom()) {
-                  sf = scalingFactors[j];
-                  match = true;  break;
-                }
-              }
-              if (!match) usage();
-            } else
-              usage();
-          } else if (argv[i].equalsIgnoreCase("-hflip"))
-            xformOp = TJTransform.OP_HFLIP;
-          else if (argv[i].equalsIgnoreCase("-vflip"))
-            xformOp = TJTransform.OP_VFLIP;
-          else if (argv[i].equalsIgnoreCase("-transpose"))
-            xformOp = TJTransform.OP_TRANSPOSE;
-          else if (argv[i].equalsIgnoreCase("-transverse"))
-            xformOp = TJTransform.OP_TRANSVERSE;
-          else if (argv[i].equalsIgnoreCase("-rot90"))
-            xformOp = TJTransform.OP_ROT90;
-          else if (argv[i].equalsIgnoreCase("-rot180"))
-            xformOp = TJTransform.OP_ROT180;
-          else if (argv[i].equalsIgnoreCase("-rot270"))
-            xformOp = TJTransform.OP_ROT270;
-          else if (argv[i].equalsIgnoreCase("-grayscale"))
-            xformOpt |= TJTransform.OPT_GRAY;
-          else if (argv[i].equalsIgnoreCase("-nooutput"))
-            xformOpt |= TJTransform.OPT_NOOUTPUT;
-          else if (argv[i].equalsIgnoreCase("-copynone"))
-            xformOpt |= TJTransform.OPT_COPYNONE;
-          else if (argv[i].equalsIgnoreCase("-benchtime") &&
-                   i < argv.length - 1) {
-            double temp = -1;
-
-            try {
-              temp = Double.parseDouble(argv[++i]);
-            } catch (NumberFormatException e) {}
-            if (temp > 0.0)
-              benchTime = temp;
-            else
-              usage();
-          } else if (argv[i].equalsIgnoreCase("-warmup") &&
-                     i < argv.length - 1) {
-            double temp = -1;
-
-            try {
-              temp = Double.parseDouble(argv[++i]);
-            } catch (NumberFormatException e) {}
-            if (temp >= 0.0) {
-              warmup = temp;
-              System.out.format("Warmup time = %.1f seconds\n\n", warmup);
-            } else
-              usage();
-          } else if (argv[i].equalsIgnoreCase("-yuv")) {
-            System.out.println("Testing YUV planar encoding/decoding\n");
-            doYUV = true;
-          } else if (argv[i].equalsIgnoreCase("-yuvpad") &&
-                     i < argv.length - 1) {
-            int temp = 0;
-
-            try {
-              temp = Integer.parseInt(argv[++i]);
-            } catch (NumberFormatException e) {}
-            if (temp >= 1)
-              yuvPad = temp;
-          } else if (argv[i].equalsIgnoreCase("-subsamp") &&
-                     i < argv.length - 1) {
-            i++;
-            if (argv[i].toUpperCase().startsWith("G"))
-              subsamp = TJ.SAMP_GRAY;
-            else if (argv[i].equals("444"))
-              subsamp = TJ.SAMP_444;
-            else if (argv[i].equals("422"))
-              subsamp = TJ.SAMP_422;
-            else if (argv[i].equals("440"))
-              subsamp = TJ.SAMP_440;
-            else if (argv[i].equals("420"))
-              subsamp = TJ.SAMP_420;
-            else if (argv[i].equals("411"))
-              subsamp = TJ.SAMP_411;
-          } else if (argv[i].equalsIgnoreCase("-componly"))
-            compOnly = true;
-          else if (argv[i].equalsIgnoreCase("-nowrite"))
-            write = false;
-          else if (argv[i].equalsIgnoreCase("-stoponwarning"))
-            flags |= TJ.FLAG_STOPONWARNING;
-          else usage();
-        }
-      }
-
-      if (sf == null)
-        sf = new TJScalingFactor(1, 1);
-
-      if ((sf.getNum() != 1 || sf.getDenom() != 1) && doTile) {
-        System.out.println("Disabling tiled compression/decompression tests, because those tests do not");
-        System.out.println("work when scaled decompression is enabled.");
-        doTile = false;
-      }
-
-      if (!decompOnly) {
-        int[] width = new int[1], height = new int[1];
-
-        srcBuf = loadImage(argv[0], width, height, pf);
-        w = width[0];  h = height[0];
-        int index = -1;
-        if ((index = argv[0].lastIndexOf('.')) >= 0)
-          argv[0] = argv[0].substring(0, index);
-      }
-
-      if (quiet == 1 && !decompOnly) {
-        System.out.println("All performance values in Mpixels/sec\n");
-        System.out.format("Bitmap     JPEG     JPEG  %s  %s   ",
-                          (doTile ? "Tile " : "Image"),
-                          (doTile ? "Tile " : "Image"));
-        if (doYUV)
-          System.out.print("Encode  ");
-        System.out.print("Comp    Comp    Decomp  ");
-        if (doYUV)
-          System.out.print("Decode");
-        System.out.print("\n");
-        System.out.print("Format     Subsamp  Qual  Width  Height  ");
-        if (doYUV)
-          System.out.print("Perf    ");
-        System.out.print("Perf    Ratio   Perf    ");
-        if (doYUV)
-          System.out.print("Perf");
-        System.out.println("\n");
-      }
-
-      if (decompOnly) {
-        decompTest(argv[0]);
-        System.out.println("");
-        System.exit(retval);
-      }
-
-      System.gc();
-      if (subsamp >= 0 && subsamp < TJ.NUMSAMP) {
-        for (int i = maxQual; i >= minQual; i--)
-          fullTest(srcBuf, w, h, subsamp, i, argv[0]);
-        System.out.println("");
-      } else {
-        for (int i = maxQual; i >= minQual; i--)
-          fullTest(srcBuf, w, h, TJ.SAMP_GRAY, i, argv[0]);
-        System.out.println("");
-        System.gc();
-        for (int i = maxQual; i >= minQual; i--)
-          fullTest(srcBuf, w, h, TJ.SAMP_420, i, argv[0]);
-        System.out.println("");
-        System.gc();
-        for (int i = maxQual; i >= minQual; i--)
-          fullTest(srcBuf, w, h, TJ.SAMP_422, i, argv[0]);
-        System.out.println("");
-        System.gc();
-        for (int i = maxQual; i >= minQual; i--)
-          fullTest(srcBuf, w, h, TJ.SAMP_444, i, argv[0]);
-        System.out.println("");
-      }
-
-    } catch (Exception e) {
-      if (e instanceof TJException) {
-        TJException tje = (TJException)e;
-
-        System.out.println((tje.getErrorCode() == TJ.ERR_WARNING ?
-                            "WARNING: " : "ERROR: ") + tje.getMessage());
-      } else
-        System.out.println("ERROR: " + e.getMessage());
-      e.printStackTrace();
-      retval = -1;
-    }
-
-    System.exit(retval);
-  }
-
-}
diff --git a/src/third_party/libjpeg-turbo/java/TJExample.java b/src/third_party/libjpeg-turbo/java/TJExample.java
deleted file mode 100644
index 7859886..0000000
--- a/src/third_party/libjpeg-turbo/java/TJExample.java
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (C)2011-2012, 2014-2015, 2017-2018 D. R. Commander.
- *                                              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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-/*
- * This program demonstrates how to compress, decompress, and transform JPEG
- * images using the TurboJPEG Java API
- */
-
-import java.io.*;
-import java.awt.*;
-import java.awt.image.*;
-import java.nio.*;
-import javax.imageio.*;
-import javax.swing.*;
-import org.libjpegturbo.turbojpeg.*;
-
-
-@SuppressWarnings("checkstyle:JavadocType")
-class TJExample implements TJCustomFilter {
-
-  static final String CLASS_NAME =
-    new TJExample().getClass().getName();
-
-  static final int DEFAULT_SUBSAMP = TJ.SAMP_444;
-  static final int DEFAULT_QUALITY = 95;
-
-
-  static final String[] SUBSAMP_NAME = {
-    "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
-  };
-
-  static final String[] COLORSPACE_NAME = {
-    "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
-  };
-
-
-  /* DCT filter example.  This produces a negative of the image. */
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
-                           Rectangle planeRegion, int componentIndex,
-                           int transformIndex, TJTransform transform)
-                           throws TJException {
-    for (int i = 0; i < bufferRegion.width * bufferRegion.height; i++) {
-      coeffBuffer.put(i, (short)(-coeffBuffer.get(i)));
-    }
-  }
-
-
-  static void usage() throws Exception {
-    System.out.println("\nUSAGE: java [Java options] " + CLASS_NAME +
-                       " <Input image> <Output image> [options]\n");
-
-    System.out.println("Input and output images can be in any image format that the Java Image I/O");
-    System.out.println("extensions understand.  If either filename ends in a .jpg extension, then");
-    System.out.println("the TurboJPEG API will be used to compress or decompress the image.\n");
-
-    System.out.println("Compression Options (used if the output image is a JPEG image)");
-    System.out.println("--------------------------------------------------------------\n");
-
-    System.out.println("-subsamp <444|422|420|gray> = Apply this level of chrominance subsampling when");
-    System.out.println("     compressing the output image.  The default is to use the same level of");
-    System.out.println("     subsampling as in the input image, if the input image is also a JPEG");
-    System.out.println("     image, or to use grayscale if the input image is a grayscale non-JPEG");
-    System.out.println("     image, or to use " +
-                       SUBSAMP_NAME[DEFAULT_SUBSAMP] +
-                       " subsampling otherwise.\n");
-
-    System.out.println("-q <1-100> = Compress the output image with this JPEG quality level");
-    System.out.println("     (default = " + DEFAULT_QUALITY + ").\n");
-
-    System.out.println("Decompression Options (used if the input image is a JPEG image)");
-    System.out.println("---------------------------------------------------------------\n");
-
-    System.out.println("-scale M/N = Scale the input image by a factor of M/N when decompressing it.");
-    System.out.print("(M/N = ");
-    for (int i = 0; i < SCALING_FACTORS.length; i++) {
-      System.out.print(SCALING_FACTORS[i].getNum() + "/" +
-                       SCALING_FACTORS[i].getDenom());
-      if (SCALING_FACTORS.length == 2 && i != SCALING_FACTORS.length - 1)
-        System.out.print(" or ");
-      else if (SCALING_FACTORS.length > 2) {
-        if (i != SCALING_FACTORS.length - 1)
-          System.out.print(", ");
-        if (i == SCALING_FACTORS.length - 2)
-          System.out.print("or ");
-      }
-    }
-    System.out.println(")\n");
-
-    System.out.println("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =");
-    System.out.println("     Perform one of these lossless transform operations on the input image");
-    System.out.println("     prior to decompressing it (these options are mutually exclusive.)\n");
-
-    System.out.println("-grayscale = Perform lossless grayscale conversion on the input image prior");
-    System.out.println("     to decompressing it (can be combined with the other transform operations");
-    System.out.println("     above.)\n");
-
-    System.out.println("-crop WxH+X+Y = Perform lossless cropping on the input image prior to");
-    System.out.println("     decompressing it.  X and Y specify the upper left corner of the cropping");
-    System.out.println("     region, and W and H specify the width and height of the cropping region.");
-    System.out.println("     X and Y must be evenly divible by the MCU block size (8x8 if the input");
-    System.out.println("     image was compressed using no subsampling or grayscale, 16x8 if it was");
-    System.out.println("     compressed using 4:2:2 subsampling, or 16x16 if it was compressed using");
-    System.out.println("     4:2:0 subsampling.)\n");
-
-    System.out.println("General Options");
-    System.out.println("---------------\n");
-
-    System.out.println("-display = Display output image (Output filename need not be specified in this");
-    System.out.println("     case.)\n");
-
-    System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available in");
-    System.out.println("     the underlying codec.\n");
-
-    System.out.println("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying");
-    System.out.println("     codec.\n");
-
-    System.out.println("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the");
-    System.out.println("     underlying codec.\n");
-
-    System.exit(1);
-  }
-
-
-  public static void main(String[] argv) {
-
-    try {
-
-      TJScalingFactor scalingFactor = new TJScalingFactor(1, 1);
-      int outSubsamp = -1, outQual = -1;
-      TJTransform xform = new TJTransform();
-      boolean display = false;
-      int flags = 0;
-      int width, height;
-      String inFormat = "jpg", outFormat = "jpg";
-      BufferedImage img = null;
-      byte[] imgBuf = null;
-
-      if (argv.length < 2)
-        usage();
-
-      if (argv[1].substring(0, 2).equalsIgnoreCase("-d"))
-        display = true;
-
-      /* Parse arguments. */
-      for (int i = 2; i < argv.length; i++) {
-        if (argv[i].length() < 2)
-          continue;
-        else if (argv[i].length() > 2 &&
-                 argv[i].substring(0, 3).equalsIgnoreCase("-sc") &&
-                 i < argv.length - 1) {
-          int match = 0;
-          String[] scaleArg = argv[++i].split("/");
-          if (scaleArg.length == 2) {
-            TJScalingFactor tempsf =
-              new TJScalingFactor(Integer.parseInt(scaleArg[0]),
-                                  Integer.parseInt(scaleArg[1]));
-            for (int j = 0; j < SCALING_FACTORS.length; j++) {
-              if (tempsf.equals(SCALING_FACTORS[j])) {
-                scalingFactor = SCALING_FACTORS[j];
-                match = 1;
-                break;
-              }
-            }
-          }
-          if (match != 1)
-            usage();
-        } else if (argv[i].length() > 2 &&
-                   argv[i].substring(0, 3).equalsIgnoreCase("-su") &&
-                   i < argv.length - 1) {
-          i++;
-          if (argv[i].substring(0, 1).equalsIgnoreCase("g"))
-            outSubsamp = TJ.SAMP_GRAY;
-          else if (argv[i].equals("444"))
-            outSubsamp = TJ.SAMP_444;
-          else if (argv[i].equals("422"))
-            outSubsamp = TJ.SAMP_422;
-          else if (argv[i].equals("420"))
-            outSubsamp = TJ.SAMP_420;
-          else
-            usage();
-        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-q") &&
-                   i < argv.length - 1) {
-          outQual = Integer.parseInt(argv[++i]);
-          if (outQual < 1 || outQual > 100)
-            usage();
-        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-g"))
-          xform.options |= TJTransform.OPT_GRAY;
-        else if (argv[i].equalsIgnoreCase("-hflip"))
-          xform.op = TJTransform.OP_HFLIP;
-        else if (argv[i].equalsIgnoreCase("-vflip"))
-          xform.op = TJTransform.OP_VFLIP;
-        else if (argv[i].equalsIgnoreCase("-transpose"))
-          xform.op = TJTransform.OP_TRANSPOSE;
-        else if (argv[i].equalsIgnoreCase("-transverse"))
-          xform.op = TJTransform.OP_TRANSVERSE;
-        else if (argv[i].equalsIgnoreCase("-rot90"))
-          xform.op = TJTransform.OP_ROT90;
-        else if (argv[i].equalsIgnoreCase("-rot180"))
-          xform.op = TJTransform.OP_ROT180;
-        else if (argv[i].equalsIgnoreCase("-rot270"))
-          xform.op = TJTransform.OP_ROT270;
-        else if (argv[i].equalsIgnoreCase("-custom"))
-          xform.cf = new TJExample();
-        else if (argv[i].length() > 2 &&
-                 argv[i].substring(0, 2).equalsIgnoreCase("-c") &&
-                 i < argv.length - 1) {
-          String[] cropArg = argv[++i].split("[x\\+]");
-          if (cropArg.length != 4)
-            usage();
-          xform.width = Integer.parseInt(cropArg[0]);
-          xform.height = Integer.parseInt(cropArg[1]);
-          xform.x = Integer.parseInt(cropArg[2]);
-          xform.y = Integer.parseInt(cropArg[3]);
-          if (xform.x < 0 || xform.y < 0 || xform.width < 1 ||
-              xform.height < 1)
-            usage();
-          xform.options |= TJTransform.OPT_CROP;
-        } else if (argv[i].substring(0, 2).equalsIgnoreCase("-d"))
-          display = true;
-        else if (argv[i].equalsIgnoreCase("-fastupsample")) {
-          System.out.println("Using fast upsampling code");
-          flags |= TJ.FLAG_FASTUPSAMPLE;
-        } else if (argv[i].equalsIgnoreCase("-fastdct")) {
-          System.out.println("Using fastest DCT/IDCT algorithm");
-          flags |= TJ.FLAG_FASTDCT;
-        } else if (argv[i].equalsIgnoreCase("-accuratedct")) {
-          System.out.println("Using most accurate DCT/IDCT algorithm");
-          flags |= TJ.FLAG_ACCURATEDCT;
-        } else usage();
-      }
-
-      /* Determine input and output image formats based on file extensions. */
-      String[] inFileTokens = argv[0].split("\\.");
-      if (inFileTokens.length > 1)
-        inFormat = inFileTokens[inFileTokens.length - 1];
-      String[] outFileTokens;
-      if (display)
-        outFormat = "bmp";
-      else {
-        outFileTokens = argv[1].split("\\.");
-        if (outFileTokens.length > 1)
-          outFormat = outFileTokens[outFileTokens.length - 1];
-      }
-
-      if (inFormat.equalsIgnoreCase("jpg")) {
-        /* Input image is a JPEG image.  Decompress and/or transform it. */
-        boolean doTransform = (xform.op != TJTransform.OP_NONE ||
-                               xform.options != 0 || xform.cf != null);
-
-        /* Read the JPEG file into memory. */
-        File jpegFile = new File(argv[0]);
-        FileInputStream fis = new FileInputStream(jpegFile);
-        int jpegSize = fis.available();
-        if (jpegSize < 1) {
-          System.out.println("Input file contains no data");
-          System.exit(1);
-        }
-        byte[] jpegBuf = new byte[jpegSize];
-        fis.read(jpegBuf);
-        fis.close();
-
-        TJDecompressor tjd;
-        if (doTransform) {
-          /* Transform it. */
-          TJTransformer tjt = new TJTransformer(jpegBuf);
-          TJTransform[] xforms = new TJTransform[1];
-          xforms[0] = xform;
-          xforms[0].options |= TJTransform.OPT_TRIM;
-          TJDecompressor[] tjds = tjt.transform(xforms, 0);
-          tjd = tjds[0];
-          tjt.close();
-        } else
-          tjd = new TJDecompressor(jpegBuf);
-
-        width = tjd.getWidth();
-        height = tjd.getHeight();
-        int inSubsamp = tjd.getSubsamp();
-        int inColorspace = tjd.getColorspace();
-
-        System.out.println((doTransform ? "Transformed" : "Input") +
-                           " Image (jpg):  " + width + " x " + height +
-                           " pixels, " + SUBSAMP_NAME[inSubsamp] +
-                           " subsampling, " + COLORSPACE_NAME[inColorspace]);
-
-        if (outFormat.equalsIgnoreCase("jpg") && doTransform &&
-            scalingFactor.isOne() && outSubsamp < 0 && outQual < 0) {
-          /* Input image has been transformed, and no re-compression options
-             have been selected.  Write the transformed image to disk and
-             exit. */
-          File outFile = new File(argv[1]);
-          FileOutputStream fos = new FileOutputStream(outFile);
-          fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
-          fos.close();
-          System.exit(0);
-        }
-
-        /* Scaling and/or a non-JPEG output image format and/or compression
-           options have been selected, so we need to decompress the
-           input/transformed image. */
-        width = scalingFactor.getScaled(width);
-        height = scalingFactor.getScaled(height);
-        if (outSubsamp < 0)
-          outSubsamp = inSubsamp;
-
-        if (!outFormat.equalsIgnoreCase("jpg"))
-          img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB,
-                               flags);
-        else
-          imgBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags);
-        tjd.close();
-      } else {
-        /* Input image is not a JPEG image.  Load it into memory. */
-        img = ImageIO.read(new File(argv[0]));
-        if (img == null)
-          throw new Exception("Input image type not supported.");
-        width = img.getWidth();
-        height = img.getHeight();
-        if (outSubsamp < 0) {
-          if (img.getType() == BufferedImage.TYPE_BYTE_GRAY)
-            outSubsamp = TJ.SAMP_GRAY;
-          else
-            outSubsamp = DEFAULT_SUBSAMP;
-        }
-        System.out.println("Input Image:  " + width + " x " + height +
-                           " pixels");
-      }
-      System.gc();
-      if (!display)
-        System.out.print("Output Image (" + outFormat + "):  " + width +
-                         " x " + height + " pixels");
-
-      if (display) {
-        /* Display the uncompressed image */
-        ImageIcon icon = new ImageIcon(img);
-        JLabel label = new JLabel(icon, JLabel.CENTER);
-        JOptionPane.showMessageDialog(null, label, "Output Image",
-                                      JOptionPane.PLAIN_MESSAGE);
-      } else if (outFormat.equalsIgnoreCase("jpg")) {
-        /* Output image format is JPEG.  Compress the uncompressed image. */
-        if (outQual < 0)
-          outQual = DEFAULT_QUALITY;
-        System.out.println(", " + SUBSAMP_NAME[outSubsamp] +
-                           " subsampling, quality = " + outQual);
-
-        TJCompressor tjc = new TJCompressor();
-        tjc.setSubsamp(outSubsamp);
-        tjc.setJPEGQuality(outQual);
-        if (img != null)
-          tjc.setSourceImage(img, 0, 0, 0, 0);
-        else
-          tjc.setSourceImage(imgBuf, 0, 0, width, 0, height, TJ.PF_BGRX);
-        byte[] jpegBuf = tjc.compress(flags);
-        int jpegSize = tjc.getCompressedSize();
-        tjc.close();
-
-        /* Write the JPEG image to disk. */
-        File outFile = new File(argv[1]);
-        FileOutputStream fos = new FileOutputStream(outFile);
-        fos.write(jpegBuf, 0, jpegSize);
-        fos.close();
-      } else {
-        /* Output image format is not JPEG.  Save the uncompressed image
-           directly to disk. */
-        System.out.print("\n");
-        File outFile = new File(argv[1]);
-        ImageIO.write(img, outFormat, outFile);
-      }
-
-    } catch (Exception e) {
-      e.printStackTrace();
-      System.exit(-1);
-    }
-  }
-
-  static final TJScalingFactor[] SCALING_FACTORS =
-    TJ.getScalingFactors();
-};
diff --git a/src/third_party/libjpeg-turbo/java/TJUnitTest.java b/src/third_party/libjpeg-turbo/java/TJUnitTest.java
deleted file mode 100644
index 91ad5fd..0000000
--- a/src/third_party/libjpeg-turbo/java/TJUnitTest.java
+++ /dev/null
@@ -1,960 +0,0 @@
-/*
- * Copyright (C)2011-2018 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-/*
- * This program tests the various code paths in the TurboJPEG JNI Wrapper
- */
-
-import java.io.*;
-import java.util.*;
-import java.awt.image.*;
-import javax.imageio.*;
-import java.nio.*;
-import org.libjpegturbo.turbojpeg.*;
-
-@SuppressWarnings("checkstyle:JavadocType")
-final class TJUnitTest {
-
-  private TJUnitTest() {}
-
-  static final String CLASS_NAME =
-    new TJUnitTest().getClass().getName();
-
-  static void usage() {
-    System.out.println("\nUSAGE: java " + CLASS_NAME + " [options]\n");
-    System.out.println("Options:");
-    System.out.println("-yuv = test YUV encoding/decoding support");
-    System.out.println("-noyuvpad = do not pad each line of each Y, U, and V plane to the nearest");
-    System.out.println("            4-byte boundary");
-    System.out.println("-bi = test BufferedImage support\n");
-    System.exit(1);
-  }
-
-  static final String[] SUBNAME_LONG = {
-    "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
-  };
-  static final String[] SUBNAME = {
-    "444", "422", "420", "GRAY", "440", "411"
-  };
-
-  static final String[] PIXFORMATSTR = {
-    "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
-    "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
-  };
-
-  static final int[] FORMATS_3BYTE = {
-    TJ.PF_RGB, TJ.PF_BGR
-  };
-  static final int[] FORMATS_3BYTEBI = {
-    BufferedImage.TYPE_3BYTE_BGR
-  };
-  static final int[] FORMATS_4BYTE = {
-    TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB, TJ.PF_CMYK
-  };
-  static final int[] FORMATS_4BYTEBI = {
-    BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
-    BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
-    BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
-  };
-  static final int[] FORMATS_GRAY = {
-    TJ.PF_GRAY
-  };
-  static final int[] FORMATS_GRAYBI = {
-    BufferedImage.TYPE_BYTE_GRAY
-  };
-  static final int[] FORMATS_RGB = {
-    TJ.PF_RGB
-  };
-
-  private static boolean doYUV = false;
-  private static int pad = 4;
-  private static boolean bi = false;
-
-  private static int exitStatus = 0;
-
-  static int biTypePF(int biType) {
-    ByteOrder byteOrder = ByteOrder.nativeOrder();
-    switch (biType) {
-    case BufferedImage.TYPE_3BYTE_BGR:
-      return TJ.PF_BGR;
-    case BufferedImage.TYPE_4BYTE_ABGR:
-    case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-      return TJ.PF_ABGR;
-    case BufferedImage.TYPE_BYTE_GRAY:
-      return TJ.PF_GRAY;
-    case BufferedImage.TYPE_INT_BGR:
-      return TJ.PF_RGBX;
-    case BufferedImage.TYPE_INT_RGB:
-      return TJ.PF_BGRX;
-    case BufferedImage.TYPE_INT_ARGB:
-    case BufferedImage.TYPE_INT_ARGB_PRE:
-      return TJ.PF_BGRA;
-    default:
-      return 0;
-    }
-  }
-
-  static String biTypeStr(int biType) {
-    switch (biType) {
-    case BufferedImage.TYPE_3BYTE_BGR:
-      return "3BYTE_BGR";
-    case BufferedImage.TYPE_4BYTE_ABGR:
-      return "4BYTE_ABGR";
-    case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-      return "4BYTE_ABGR_PRE";
-    case BufferedImage.TYPE_BYTE_GRAY:
-      return "BYTE_GRAY";
-    case BufferedImage.TYPE_INT_BGR:
-      return "INT_BGR";
-    case BufferedImage.TYPE_INT_RGB:
-      return "INT_RGB";
-    case BufferedImage.TYPE_INT_ARGB:
-      return "INT_ARGB";
-    case BufferedImage.TYPE_INT_ARGB_PRE:
-      return "INT_ARGB_PRE";
-    default:
-      return "Unknown";
-    }
-  }
-
-  static void initBuf(byte[] buf, int w, int pitch, int h, int pf, int flags)
-                      throws Exception {
-    int roffset = TJ.getRedOffset(pf);
-    int goffset = TJ.getGreenOffset(pf);
-    int boffset = TJ.getBlueOffset(pf);
-    int aoffset = TJ.getAlphaOffset(pf);
-    int ps = TJ.getPixelSize(pf);
-    int index, row, col, halfway = 16;
-
-    if (pf == TJ.PF_GRAY) {
-      Arrays.fill(buf, (byte)0);
-      for (row = 0; row < h; row++) {
-        for (col = 0; col < w; col++) {
-          if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-            index = pitch * (h - row - 1) + col;
-          else
-            index = pitch * row + col;
-          if (((row / 8) + (col / 8)) % 2 == 0)
-            buf[index] = (row < halfway) ? (byte)255 : 0;
-          else
-            buf[index] = (row < halfway) ? 76 : (byte)226;
-        }
-      }
-      return;
-    }
-    if (pf == TJ.PF_CMYK) {
-      Arrays.fill(buf, (byte)255);
-      for (row = 0; row < h; row++) {
-        for (col = 0; col < w; col++) {
-          if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-            index = (h - row - 1) * w + col;
-          else
-            index = row * w + col;
-          if (((row / 8) + (col / 8)) % 2 == 0) {
-            if (row >= halfway) buf[index * ps + 3] = 0;
-          } else {
-            buf[index * ps + 2] = 0;
-            if (row < halfway)
-              buf[index * ps + 1] = 0;
-          }
-        }
-      }
-      return;
-    }
-
-    Arrays.fill(buf, (byte)0);
-    for (row = 0; row < h; row++) {
-      for (col = 0; col < w; col++) {
-        if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-          index = pitch * (h - row - 1) + col * ps;
-        else
-          index = pitch * row + col * ps;
-        if (((row / 8) + (col / 8)) % 2 == 0) {
-          if (row < halfway) {
-            buf[index + roffset] = (byte)255;
-            buf[index + goffset] = (byte)255;
-            buf[index + boffset] = (byte)255;
-          }
-        } else {
-          buf[index + roffset] = (byte)255;
-          if (row >= halfway)
-            buf[index + goffset] = (byte)255;
-        }
-        if (aoffset >= 0)
-          buf[index + aoffset] = (byte)255;
-      }
-    }
-  }
-
-  static void initIntBuf(int[] buf, int w, int pitch, int h, int pf, int flags)
-                         throws Exception {
-    int rshift = TJ.getRedOffset(pf) * 8;
-    int gshift = TJ.getGreenOffset(pf) * 8;
-    int bshift = TJ.getBlueOffset(pf) * 8;
-    int ashift = TJ.getAlphaOffset(pf) * 8;
-    int index, row, col, halfway = 16;
-
-    Arrays.fill(buf, 0);
-    for (row = 0; row < h; row++) {
-      for (col = 0; col < w; col++) {
-        if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-          index = pitch * (h - row - 1) + col;
-        else
-          index = pitch * row + col;
-        if (((row / 8) + (col / 8)) % 2 == 0) {
-          if (row < halfway) {
-            buf[index] |= (255 << rshift);
-            buf[index] |= (255 << gshift);
-            buf[index] |= (255 << bshift);
-          }
-        } else {
-          buf[index] |= (255 << rshift);
-          if (row >= halfway)
-            buf[index] |= (255 << gshift);
-        }
-        if (ashift >= 0)
-          buf[index] |= (255 << ashift);
-      }
-    }
-  }
-
-  static void initImg(BufferedImage img, int pf, int flags) throws Exception {
-    WritableRaster wr = img.getRaster();
-    int imgType = img.getType();
-
-    if (imgType == BufferedImage.TYPE_INT_RGB ||
-        imgType == BufferedImage.TYPE_INT_BGR ||
-        imgType == BufferedImage.TYPE_INT_ARGB ||
-        imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
-      SinglePixelPackedSampleModel sm =
-        (SinglePixelPackedSampleModel)img.getSampleModel();
-      int pitch = sm.getScanlineStride();
-      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
-      int[] buf = db.getData();
-      initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
-    } else {
-      ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
-      int pitch = sm.getScanlineStride();
-      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
-      byte[] buf = db.getData();
-      initBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
-    }
-  }
-
-  static void checkVal(int row, int col, int v, String vname, int cv)
-                       throws Exception {
-    v = (v < 0) ? v + 256 : v;
-    if (v < cv - 1 || v > cv + 1) {
-      throw new Exception("Comp. " + vname + " at " + row + "," + col +
-                          " should be " + cv + ", not " + v);
-    }
-  }
-
-  static void checkVal0(int row, int col, int v, String vname)
-                        throws Exception {
-    v = (v < 0) ? v + 256 : v;
-    if (v > 1) {
-      throw new Exception("Comp. " + vname + " at " + row + "," + col +
-                          " should be 0, not " + v);
-    }
-  }
-
-  static void checkVal255(int row, int col, int v, String vname)
-                          throws Exception {
-    v = (v < 0) ? v + 256 : v;
-    if (v < 254) {
-      throw new Exception("Comp. " + vname + " at " + row + "," + col +
-                          " should be 255, not " + v);
-    }
-  }
-
-  static int checkBuf(byte[] buf, int w, int pitch, int h, int pf, int subsamp,
-                      TJScalingFactor sf, int flags) throws Exception {
-    int roffset = TJ.getRedOffset(pf);
-    int goffset = TJ.getGreenOffset(pf);
-    int boffset = TJ.getBlueOffset(pf);
-    int aoffset = TJ.getAlphaOffset(pf);
-    int ps = TJ.getPixelSize(pf);
-    int index, row, col, retval = 1;
-    int halfway = 16 * sf.getNum() / sf.getDenom();
-    int blockSize = 8 * sf.getNum() / sf.getDenom();
-
-    try {
-
-      if (pf == TJ.PF_GRAY)
-        roffset = goffset = boffset = 0;
-
-      if (pf == TJ.PF_CMYK) {
-        for (row = 0; row < h; row++) {
-          for (col = 0; col < w; col++) {
-            if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-              index = (h - row - 1) * w + col;
-            else
-              index = row * w + col;
-            byte c = buf[index * ps];
-            byte m = buf[index * ps + 1];
-            byte y = buf[index * ps + 2];
-            byte k = buf[index * ps + 3];
-            checkVal255(row, col, c, "C");
-            if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
-              checkVal255(row, col, m, "M");
-              checkVal255(row, col, y, "Y");
-              if (row < halfway)
-                checkVal255(row, col, k, "K");
-              else
-                checkVal0(row, col, k, "K");
-            } else {
-              checkVal0(row, col, y, "Y");
-              checkVal255(row, col, k, "K");
-              if (row < halfway)
-                checkVal0(row, col, m, "M");
-              else
-                checkVal255(row, col, m, "M");
-            }
-          }
-        }
-        return 1;
-      }
-
-      for (row = 0; row < halfway; row++) {
-        for (col = 0; col < w; col++) {
-          if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-            index = pitch * (h - row - 1) + col * ps;
-          else
-            index = pitch * row + col * ps;
-          byte r = buf[index + roffset];
-          byte g = buf[index + goffset];
-          byte b = buf[index + boffset];
-          byte a = aoffset >= 0 ? buf[index + aoffset] : (byte)255;
-          if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
-            if (row < halfway) {
-              checkVal255(row, col, r, "R");
-              checkVal255(row, col, g, "G");
-              checkVal255(row, col, b, "B");
-            } else {
-              checkVal0(row, col, r, "R");
-              checkVal0(row, col, g, "G");
-              checkVal0(row, col, b, "B");
-            }
-          } else {
-            if (subsamp == TJ.SAMP_GRAY) {
-              if (row < halfway) {
-                checkVal(row, col, r, "R", 76);
-                checkVal(row, col, g, "G", 76);
-                checkVal(row, col, b, "B", 76);
-              } else {
-                checkVal(row, col, r, "R", 226);
-                checkVal(row, col, g, "G", 226);
-                checkVal(row, col, b, "B", 226);
-              }
-            } else {
-              checkVal255(row, col, r, "R");
-              if (row < halfway) {
-                checkVal0(row, col, g, "G");
-              } else {
-                checkVal255(row, col, g, "G");
-              }
-              checkVal0(row, col, b, "B");
-            }
-          }
-          checkVal255(row, col, a, "A");
-        }
-      }
-    } catch (Exception e) {
-      System.out.println("\n" + e.getMessage());
-      retval = 0;
-    }
-
-    if (retval == 0) {
-      for (row = 0; row < h; row++) {
-        for (col = 0; col < w; col++) {
-          if (pf == TJ.PF_CMYK) {
-            int c = buf[pitch * row + col * ps];
-            int m = buf[pitch * row + col * ps + 1];
-            int y = buf[pitch * row + col * ps + 2];
-            int k = buf[pitch * row + col * ps + 3];
-            if (c < 0) c += 256;
-            if (m < 0) m += 256;
-            if (y < 0) y += 256;
-            if (k < 0) k += 256;
-            System.out.format("%3d/%3d/%3d/%3d ", c, m, y, k);
-          } else {
-            int r = buf[pitch * row + col * ps + roffset];
-            int g = buf[pitch * row + col * ps + goffset];
-            int b = buf[pitch * row + col * ps + boffset];
-            if (r < 0) r += 256;
-            if (g < 0) g += 256;
-            if (b < 0) b += 256;
-            System.out.format("%3d/%3d/%3d ", r, g, b);
-          }
-        }
-        System.out.print("\n");
-      }
-    }
-    return retval;
-  }
-
-  static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
-                         int subsamp, TJScalingFactor sf, int flags)
-                         throws Exception {
-    int rshift = TJ.getRedOffset(pf) * 8;
-    int gshift = TJ.getGreenOffset(pf) * 8;
-    int bshift = TJ.getBlueOffset(pf) * 8;
-    int ashift = TJ.getAlphaOffset(pf) * 8;
-    int index, row, col, retval = 1;
-    int halfway = 16 * sf.getNum() / sf.getDenom();
-    int blockSize = 8 * sf.getNum() / sf.getDenom();
-
-    try {
-      for (row = 0; row < halfway; row++) {
-        for (col = 0; col < w; col++) {
-          if ((flags & TJ.FLAG_BOTTOMUP) != 0)
-            index = pitch * (h - row - 1) + col;
-          else
-            index = pitch * row + col;
-          int r = (buf[index] >> rshift) & 0xFF;
-          int g = (buf[index] >> gshift) & 0xFF;
-          int b = (buf[index] >> bshift) & 0xFF;
-          int a = ashift >= 0 ? (buf[index] >> ashift) & 0xFF : 255;
-          if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
-            if (row < halfway) {
-              checkVal255(row, col, r, "R");
-              checkVal255(row, col, g, "G");
-              checkVal255(row, col, b, "B");
-            } else {
-              checkVal0(row, col, r, "R");
-              checkVal0(row, col, g, "G");
-              checkVal0(row, col, b, "B");
-            }
-          } else {
-            if (subsamp == TJ.SAMP_GRAY) {
-              if (row < halfway) {
-                checkVal(row, col, r, "R", 76);
-                checkVal(row, col, g, "G", 76);
-                checkVal(row, col, b, "B", 76);
-              } else {
-                checkVal(row, col, r, "R", 226);
-                checkVal(row, col, g, "G", 226);
-                checkVal(row, col, b, "B", 226);
-              }
-            } else {
-              checkVal255(row, col, r, "R");
-              if (row < halfway) {
-                checkVal0(row, col, g, "G");
-              } else {
-                checkVal255(row, col, g, "G");
-              }
-              checkVal0(row, col, b, "B");
-            }
-          }
-          checkVal255(row, col, a, "A");
-        }
-      }
-    } catch (Exception e) {
-      System.out.println("\n" + e.getMessage());
-      retval = 0;
-    }
-
-    if (retval == 0) {
-      for (row = 0; row < h; row++) {
-        for (col = 0; col < w; col++) {
-          int r = (buf[pitch * row + col] >> rshift) & 0xFF;
-          int g = (buf[pitch * row + col] >> gshift) & 0xFF;
-          int b = (buf[pitch * row + col] >> bshift) & 0xFF;
-          if (r < 0) r += 256;
-          if (g < 0) g += 256;
-          if (b < 0) b += 256;
-          System.out.format("%3d/%3d/%3d ", r, g, b);
-        }
-        System.out.print("\n");
-      }
-    }
-    return retval;
-  }
-
-  static int checkImg(BufferedImage img, int pf, int subsamp,
-                      TJScalingFactor sf, int flags) throws Exception {
-    WritableRaster wr = img.getRaster();
-    int imgType = img.getType();
-    if (imgType == BufferedImage.TYPE_INT_RGB ||
-        imgType == BufferedImage.TYPE_INT_BGR ||
-        imgType == BufferedImage.TYPE_INT_ARGB ||
-        imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
-      SinglePixelPackedSampleModel sm =
-        (SinglePixelPackedSampleModel)img.getSampleModel();
-      int pitch = sm.getScanlineStride();
-      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
-      int[] buf = db.getData();
-      return checkIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf,
-                         subsamp, sf, flags);
-    } else {
-      ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
-      int pitch = sm.getScanlineStride();
-      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
-      byte[] buf = db.getData();
-      return checkBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, subsamp,
-                      sf, flags);
-    }
-  }
-
-  static int pad(int v, int p) {
-    return ((v + (p) - 1) & (~((p) - 1)));
-  }
-
-  static int checkBufYUV(byte[] buf, int size, int w, int h, int subsamp,
-                         TJScalingFactor sf) throws Exception {
-    int row, col;
-    int hsf = TJ.getMCUWidth(subsamp) / 8, vsf = TJ.getMCUHeight(subsamp) / 8;
-    int pw = pad(w, hsf), ph = pad(h, vsf);
-    int cw = pw / hsf, ch = ph / vsf;
-    int ypitch = pad(pw, pad), uvpitch = pad(cw, pad);
-    int retval = 1;
-    int correctsize = ypitch * ph +
-                      (subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2);
-    int halfway = 16 * sf.getNum() / sf.getDenom();
-    int blockSize = 8 * sf.getNum() / sf.getDenom();
-
-    try {
-      if (size != correctsize)
-        throw new Exception("Incorrect size " + size + ".  Should be " +
-                            correctsize);
-
-      for (row = 0; row < ph; row++) {
-        for (col = 0; col < pw; col++) {
-          byte y = buf[ypitch * row + col];
-          if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
-            if (row < halfway)
-              checkVal255(row, col, y, "Y");
-            else
-              checkVal0(row, col, y, "Y");
-          } else {
-            if (row < halfway)
-              checkVal(row, col, y, "Y", 76);
-            else
-              checkVal(row, col, y, "Y", 226);
-          }
-        }
-      }
-      if (subsamp != TJ.SAMP_GRAY) {
-        halfway = 16 / vsf * sf.getNum() / sf.getDenom();
-        for (row = 0; row < ch; row++) {
-          for (col = 0; col < cw; col++) {
-            byte u = buf[ypitch * ph + (uvpitch * row + col)],
-                 v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
-            if (((row * vsf / blockSize) + (col * hsf / blockSize)) % 2 == 0) {
-              checkVal(row, col, u, "U", 128);
-              checkVal(row, col, v, "V", 128);
-            } else {
-              if (row < halfway) {
-                checkVal(row, col, u, "U", 85);
-                checkVal255(row, col, v, "V");
-              } else {
-                checkVal0(row, col, u, "U");
-                checkVal(row, col, v, "V", 149);
-              }
-            }
-          }
-        }
-      }
-    } catch (Exception e) {
-      System.out.println("\n" + e.getMessage());
-      retval = 0;
-    }
-
-    if (retval == 0) {
-      for (row = 0; row < ph; row++) {
-        for (col = 0; col < pw; col++) {
-          int y = buf[ypitch * row + col];
-          if (y < 0) y += 256;
-          System.out.format("%3d ", y);
-        }
-        System.out.print("\n");
-      }
-      System.out.print("\n");
-      for (row = 0; row < ch; row++) {
-        for (col = 0; col < cw; col++) {
-          int u = buf[ypitch * ph + (uvpitch * row + col)];
-          if (u < 0) u += 256;
-          System.out.format("%3d ", u);
-        }
-        System.out.print("\n");
-      }
-      System.out.print("\n");
-      for (row = 0; row < ch; row++) {
-        for (col = 0; col < cw; col++) {
-          int v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
-          if (v < 0) v += 256;
-          System.out.format("%3d ", v);
-        }
-        System.out.print("\n");
-      }
-    }
-
-    return retval;
-  }
-
-  static void writeJPEG(byte[] jpegBuf, int jpegBufSize, String filename)
-                        throws Exception {
-    File file = new File(filename);
-    FileOutputStream fos = new FileOutputStream(file);
-    fos.write(jpegBuf, 0, jpegBufSize);
-    fos.close();
-  }
-
-  static int compTest(TJCompressor tjc, byte[] dstBuf, int w, int h, int pf,
-                      String baseName, int subsamp, int jpegQual, int flags)
-                      throws Exception {
-    String tempStr;
-    byte[] srcBuf = null;
-    BufferedImage img = null;
-    String pfStr, pfStrLong;
-    String buStr = (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD";
-    String buStrLong = (flags & TJ.FLAG_BOTTOMUP) != 0 ?
-                       "Bottom-Up" : "Top-Down ";
-    int size = 0, ps, imgType = pf;
-
-    if (bi) {
-      pf = biTypePF(imgType);
-      pfStr = biTypeStr(imgType);
-      pfStrLong = pfStr + " (" + PIXFORMATSTR[pf] + ")";
-    } else {
-      pfStr = PIXFORMATSTR[pf];
-      pfStrLong = pfStr;
-    }
-    ps =  TJ.getPixelSize(pf);
-
-    if (bi) {
-      img = new BufferedImage(w, h, imgType);
-      initImg(img, pf, flags);
-      tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
-                SUBNAME[subsamp] + "_Q" + jpegQual + ".png";
-      File file = new File(tempStr);
-      ImageIO.write(img, "png", file);
-      tjc.setSourceImage(img, 0, 0, 0, 0);
-    } else {
-      srcBuf = new byte[w * h * ps + 1];
-      initBuf(srcBuf, w, w * ps, h, pf, flags);
-      tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, pf);
-    }
-    Arrays.fill(dstBuf, (byte)0);
-
-    tjc.setSubsamp(subsamp);
-    tjc.setJPEGQuality(jpegQual);
-    if (doYUV) {
-      System.out.format("%s %s -> YUV %s ... ", pfStrLong, buStrLong,
-                        SUBNAME_LONG[subsamp]);
-      YUVImage yuvImage = tjc.encodeYUV(pad, flags);
-      if (checkBufYUV(yuvImage.getBuf(), yuvImage.getSize(), w, h, subsamp,
-                      new TJScalingFactor(1, 1)) == 1)
-        System.out.print("Passed.\n");
-      else {
-        System.out.print("FAILED!\n");
-        exitStatus = -1;
-      }
-
-      System.out.format("YUV %s %s -> JPEG Q%d ... ", SUBNAME_LONG[subsamp],
-                        buStrLong, jpegQual);
-      tjc.setSourceImage(yuvImage);
-    } else {
-      System.out.format("%s %s -> %s Q%d ... ", pfStrLong, buStrLong,
-                        SUBNAME_LONG[subsamp], jpegQual);
-    }
-    tjc.compress(dstBuf, flags);
-    size = tjc.getCompressedSize();
-
-    tempStr = baseName + "_enc_" + pfStr + "_" + buStr + "_" +
-              SUBNAME[subsamp] + "_Q" + jpegQual + ".jpg";
-    writeJPEG(dstBuf, size, tempStr);
-    System.out.println("Done.\n  Result in " + tempStr);
-
-    return size;
-  }
-
-  static void decompTest(TJDecompressor tjd, byte[] jpegBuf, int jpegSize,
-                         int w, int h, int pf, String baseName, int subsamp,
-                         int flags, TJScalingFactor sf) throws Exception {
-    String pfStr, pfStrLong, tempStr;
-    String buStrLong = (flags & TJ.FLAG_BOTTOMUP) != 0 ?
-                       "Bottom-Up" : "Top-Down ";
-    int scaledWidth = sf.getScaled(w);
-    int scaledHeight = sf.getScaled(h);
-    int temp1, temp2, imgType = pf;
-    BufferedImage img = null;
-    byte[] dstBuf = null;
-
-    if (bi) {
-      pf = biTypePF(imgType);
-      pfStr = biTypeStr(imgType);
-      pfStrLong = pfStr + " (" + PIXFORMATSTR[pf] + ")";
-    } else {
-      pfStr = PIXFORMATSTR[pf];
-      pfStrLong = pfStr;
-    }
-
-    tjd.setSourceImage(jpegBuf, jpegSize);
-    if (tjd.getWidth() != w || tjd.getHeight() != h ||
-        tjd.getSubsamp() != subsamp)
-      throw new Exception("Incorrect JPEG header");
-
-    temp1 = scaledWidth;
-    temp2 = scaledHeight;
-    temp1 = tjd.getScaledWidth(temp1, temp2);
-    temp2 = tjd.getScaledHeight(temp1, temp2);
-    if (temp1 != scaledWidth || temp2 != scaledHeight)
-      throw new Exception("Scaled size mismatch");
-
-    if (doYUV) {
-      System.out.format("JPEG -> YUV %s ", SUBNAME_LONG[subsamp]);
-      if (!sf.isOne())
-        System.out.format("%d/%d ... ", sf.getNum(), sf.getDenom());
-      else System.out.print("... ");
-      YUVImage yuvImage = tjd.decompressToYUV(scaledWidth, pad, scaledHeight,
-                                              flags);
-      if (checkBufYUV(yuvImage.getBuf(), yuvImage.getSize(), scaledWidth,
-                      scaledHeight, subsamp, sf) == 1)
-        System.out.print("Passed.\n");
-      else {
-        System.out.print("FAILED!\n");  exitStatus = -1;
-      }
-
-      System.out.format("YUV %s -> %s %s ... ", SUBNAME_LONG[subsamp],
-                        pfStrLong, buStrLong);
-      tjd.setSourceImage(yuvImage);
-    } else {
-      System.out.format("JPEG -> %s %s ", pfStrLong, buStrLong);
-      if (!sf.isOne())
-        System.out.format("%d/%d ... ", sf.getNum(), sf.getDenom());
-      else System.out.print("... ");
-    }
-    if (bi)
-      img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags);
-    else
-      dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags);
-
-    if (bi) {
-      tempStr = baseName + "_dec_" + pfStr + "_" +
-                (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
-                SUBNAME[subsamp] + "_" +
-                (double)sf.getNum() / (double)sf.getDenom() + "x" + ".png";
-      File file = new File(tempStr);
-      ImageIO.write(img, "png", file);
-    }
-
-    if ((bi && checkImg(img, pf, subsamp, sf, flags) == 1) ||
-        (!bi && checkBuf(dstBuf, scaledWidth,
-                         scaledWidth * TJ.getPixelSize(pf), scaledHeight, pf,
-                         subsamp, sf, flags) == 1))
-      System.out.print("Passed.\n");
-    else {
-      System.out.print("FAILED!\n");
-      exitStatus = -1;
-    }
-  }
-
-  static void decompTest(TJDecompressor tjd, byte[] jpegBuf, int jpegSize,
-                         int w, int h, int pf, String baseName, int subsamp,
-                         int flags) throws Exception {
-    int i;
-    TJScalingFactor[] sf = TJ.getScalingFactors();
-    for (i = 0; i < sf.length; i++) {
-      int num = sf[i].getNum();
-      int denom = sf[i].getDenom();
-      if (subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY ||
-          (subsamp == TJ.SAMP_411 && num == 1 &&
-           (denom == 2 || denom == 1)) ||
-          (subsamp != TJ.SAMP_411 && num == 1 &&
-           (denom == 4 || denom == 2 || denom == 1)))
-        decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
-                   flags, sf[i]);
-    }
-  }
-
-  static void doTest(int w, int h, int[] formats, int subsamp, String baseName)
-                     throws Exception {
-    TJCompressor tjc = null;
-    TJDecompressor tjd = null;
-    int size;
-    byte[] dstBuf;
-
-    dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
-
-    try {
-      tjc = new TJCompressor();
-      tjd = new TJDecompressor();
-
-      for (int pf : formats) {
-        if (pf < 0) continue;
-        for (int i = 0; i < 2; i++) {
-          int flags = 0;
-          if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 ||
-              subsamp == TJ.SAMP_440 || subsamp == TJ.SAMP_411)
-            flags |= TJ.FLAG_FASTUPSAMPLE;
-          if (i == 1)
-            flags |= TJ.FLAG_BOTTOMUP;
-          size = compTest(tjc, dstBuf, w, h, pf, baseName, subsamp, 100,
-                          flags);
-          decompTest(tjd, dstBuf, size, w, h, pf, baseName, subsamp, flags);
-          if (pf >= TJ.PF_RGBX && pf <= TJ.PF_XRGB && !bi) {
-            System.out.print("\n");
-            decompTest(tjd, dstBuf, size, w, h, pf + (TJ.PF_RGBA - TJ.PF_RGBX),
-                       baseName, subsamp, flags);
-          }
-          System.out.print("\n");
-        }
-      }
-      System.out.print("--------------------\n\n");
-    } catch (Exception e) {
-      if (tjc != null) tjc.close();
-      if (tjd != null) tjd.close();
-      throw e;
-    }
-    if (tjc != null) tjc.close();
-    if (tjd != null) tjd.close();
-  }
-
-  static void bufSizeTest() throws Exception {
-    int w, h, i, subsamp;
-    byte[] srcBuf, dstBuf = null;
-    YUVImage dstImage = null;
-    TJCompressor tjc = null;
-    Random r = new Random();
-
-    try {
-      tjc = new TJCompressor();
-      System.out.println("Buffer size regression test");
-      for (subsamp = 0; subsamp < TJ.NUMSAMP; subsamp++) {
-        for (w = 1; w < 48; w++) {
-          int maxh = (w == 1) ? 2048 : 48;
-          for (h = 1; h < maxh; h++) {
-            if (h % 100 == 0)
-              System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h);
-            srcBuf = new byte[w * h * 4];
-            if (doYUV)
-              dstImage = new YUVImage(w, pad, h, subsamp);
-            else
-              dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
-            for (i = 0; i < w * h * 4; i++) {
-              srcBuf[i] = (byte)(r.nextInt(2) * 255);
-            }
-            tjc.setSourceImage(srcBuf, 0, 0, w, 0, h, TJ.PF_BGRX);
-            tjc.setSubsamp(subsamp);
-            tjc.setJPEGQuality(100);
-            if (doYUV)
-              tjc.encodeYUV(dstImage, 0);
-            else
-              tjc.compress(dstBuf, 0);
-
-            srcBuf = new byte[h * w * 4];
-            if (doYUV)
-              dstImage = new YUVImage(h, pad, w, subsamp);
-            else
-              dstBuf = new byte[TJ.bufSize(h, w, subsamp)];
-            for (i = 0; i < h * w * 4; i++) {
-              srcBuf[i] = (byte)(r.nextInt(2) * 255);
-            }
-            tjc.setSourceImage(srcBuf, 0, 0, h, 0, w, TJ.PF_BGRX);
-            if (doYUV)
-              tjc.encodeYUV(dstImage, 0);
-            else
-              tjc.compress(dstBuf, 0);
-          }
-          dstImage = null;
-          dstBuf = null;
-          System.gc();
-        }
-      }
-      System.out.println("Done.      ");
-    } catch (Exception e) {
-      if (tjc != null) tjc.close();
-      throw e;
-    }
-    if (tjc != null) tjc.close();
-  }
-
-  public static void main(String[] argv) {
-    try {
-      String testName = "javatest";
-      for (int i = 0; i < argv.length; i++) {
-        if (argv[i].equalsIgnoreCase("-yuv"))
-          doYUV = true;
-        else if (argv[i].equalsIgnoreCase("-noyuvpad"))
-          pad = 1;
-        else if (argv[i].equalsIgnoreCase("-bi")) {
-          bi = true;
-          testName = "javabitest";
-        } else
-          usage();
-      }
-      if (doYUV)
-        FORMATS_4BYTE[4] = -1;
-      doTest(35, 39, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_444,
-             testName);
-      doTest(39, 41, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_444,
-             testName);
-      doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_422,
-             testName);
-      doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_422,
-             testName);
-      doTest(39, 41, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_420,
-             testName);
-      doTest(41, 35, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_420,
-             testName);
-      doTest(35, 39, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_440,
-             testName);
-      doTest(39, 41, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_440,
-             testName);
-      doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_411,
-             testName);
-      doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_411,
-             testName);
-      doTest(39, 41, bi ? FORMATS_GRAYBI : FORMATS_GRAY, TJ.SAMP_GRAY,
-             testName);
-      doTest(41, 35, bi ? FORMATS_3BYTEBI : FORMATS_3BYTE, TJ.SAMP_GRAY,
-             testName);
-      FORMATS_4BYTE[4] = -1;
-      doTest(35, 39, bi ? FORMATS_4BYTEBI : FORMATS_4BYTE, TJ.SAMP_GRAY,
-             testName);
-      if (!bi)
-        bufSizeTest();
-      if (doYUV && !bi) {
-        System.out.print("\n--------------------\n\n");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_444, "javatest_yuv0");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_422, "javatest_yuv0");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_420, "javatest_yuv0");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_440, "javatest_yuv0");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_411, "javatest_yuv0");
-        doTest(48, 48, FORMATS_RGB, TJ.SAMP_GRAY, "javatest_yuv0");
-        doTest(48, 48, FORMATS_GRAY, TJ.SAMP_GRAY, "javatest_yuv0");
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-      exitStatus = -1;
-    }
-    System.exit(exitStatus);
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/java/doc/allclasses-frame.html b/src/third_party/libjpeg-turbo/java/doc/allclasses-frame.html
deleted file mode 100644
index fecac06..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/allclasses-frame.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>All Classes</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<h1 class="bar">All Classes</h1>
-<div class="indexContainer">
-<ul>
-<li><a href="org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJ</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJCompressor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg" target="classFrame"><i>TJCustomFilter</i></a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJDecompressor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJException</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJScalingFactor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJTransform</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJTransformer</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">YUVImage</a></li>
-</ul>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/allclasses-noframe.html b/src/third_party/libjpeg-turbo/java/doc/allclasses-noframe.html
deleted file mode 100644
index 1f7fd3c..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/allclasses-noframe.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>All Classes</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<h1 class="bar">All Classes</h1>
-<div class="indexContainer">
-<ul>
-<li><a href="org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><i>TJCustomFilter</i></a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></li>
-<li><a href="org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></li>
-</ul>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/constant-values.html b/src/third_party/libjpeg-turbo/java/doc/constant-values.html
deleted file mode 100644
index fb33327..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/constant-values.html
+++ /dev/null
@@ -1,532 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Constant Field Values</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="Constant Field Values";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
-<li><a href="constant-values.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 title="Constant Field Values" class="title">Constant Field Values</h1>
-<h2 title="Contents">Contents</h2>
-<ul>
-<li><a href="#org.libjpegturbo">org.libjpegturbo.*</a></li>
-</ul>
-</div>
-<div class="constantValuesContainer"><a name="org.libjpegturbo">
-<!--   -->
-</a>
-<h2 title="org.libjpegturbo">org.libjpegturbo.*</h2>
-<ul class="blockList">
-<li class="blockList">
-<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
-<caption><span>org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th scope="col">Constant Field</th>
-<th class="colLast" scope="col">Value</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.CS_CMYK">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#CS_CMYK">CS_CMYK</a></code></td>
-<td class="colLast"><code>3</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.CS_GRAY">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#CS_GRAY">CS_GRAY</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.CS_RGB">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#CS_RGB">CS_RGB</a></code></td>
-<td class="colLast"><code>0</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.CS_YCbCr">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#CS_YCbCr">CS_YCbCr</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.CS_YCCK">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#CS_YCCK">CS_YCCK</a></code></td>
-<td class="colLast"><code>4</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.ERR_FATAL">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#ERR_FATAL">ERR_FATAL</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.ERR_WARNING">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#ERR_WARNING">ERR_WARNING</a></code></td>
-<td class="colLast"><code>0</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_ACCURATEDCT">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_ACCURATEDCT">FLAG_ACCURATEDCT</a></code></td>
-<td class="colLast"><code>4096</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_BOTTOMUP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP">FLAG_BOTTOMUP</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FASTDCT">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTDCT">FLAG_FASTDCT</a></code></td>
-<td class="colLast"><code>2048</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FASTUPSAMPLE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTUPSAMPLE">FLAG_FASTUPSAMPLE</a></code></td>
-<td class="colLast"><code>256</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FORCEMMX">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCEMMX">FLAG_FORCEMMX</a></code></td>
-<td class="colLast"><code>8</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE">FLAG_FORCESSE</a></code></td>
-<td class="colLast"><code>16</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE2">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE2">FLAG_FORCESSE2</a></code></td>
-<td class="colLast"><code>32</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE3">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE3">FLAG_FORCESSE3</a></code></td>
-<td class="colLast"><code>128</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_PROGRESSIVE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_PROGRESSIVE">FLAG_PROGRESSIVE</a></code></td>
-<td class="colLast"><code>16384</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.FLAG_STOPONWARNING">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING">FLAG_STOPONWARNING</a></code></td>
-<td class="colLast"><code>8192</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.NUMCS">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#NUMCS">NUMCS</a></code></td>
-<td class="colLast"><code>5</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.NUMERR">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#NUMERR">NUMERR</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.NUMPF">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#NUMPF">NUMPF</a></code></td>
-<td class="colLast"><code>12</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.NUMSAMP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#NUMSAMP">NUMSAMP</a></code></td>
-<td class="colLast"><code>6</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_ABGR">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_ABGR">PF_ABGR</a></code></td>
-<td class="colLast"><code>9</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_ARGB">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_ARGB">PF_ARGB</a></code></td>
-<td class="colLast"><code>10</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_BGR">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_BGR">PF_BGR</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_BGRA">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_BGRA">PF_BGRA</a></code></td>
-<td class="colLast"><code>8</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_BGRX">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_BGRX">PF_BGRX</a></code></td>
-<td class="colLast"><code>3</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_CMYK">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_CMYK">PF_CMYK</a></code></td>
-<td class="colLast"><code>11</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_GRAY">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_GRAY">PF_GRAY</a></code></td>
-<td class="colLast"><code>6</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_RGB">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_RGB">PF_RGB</a></code></td>
-<td class="colLast"><code>0</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_RGBA">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_RGBA">PF_RGBA</a></code></td>
-<td class="colLast"><code>7</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_RGBX">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_RGBX">PF_RGBX</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_XBGR">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_XBGR">PF_XBGR</a></code></td>
-<td class="colLast"><code>4</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.PF_XRGB">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#PF_XRGB">PF_XRGB</a></code></td>
-<td class="colLast"><code>5</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_411">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_411">SAMP_411</a></code></td>
-<td class="colLast"><code>5</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_420">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_420">SAMP_420</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_422">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_422">SAMP_422</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_440">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_440">SAMP_440</a></code></td>
-<td class="colLast"><code>4</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_444">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_444">SAMP_444</a></code></td>
-<td class="colLast"><code>0</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJ.SAMP_GRAY">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJ.html#SAMP_GRAY">SAMP_GRAY</a></code></td>
-<td class="colLast"><code>3</code></td>
-</tr>
-</tbody>
-</table>
-</li>
-<li class="blockList">
-<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
-<caption><span>org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th scope="col">Constant Field</th>
-<th class="colLast" scope="col">Value</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.NUMOP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#NUMOP">NUMOP</a></code></td>
-<td class="colLast"><code>8</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_HFLIP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_HFLIP">OP_HFLIP</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_NONE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_NONE">OP_NONE</a></code></td>
-<td class="colLast"><code>0</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_ROT180">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT180">OP_ROT180</a></code></td>
-<td class="colLast"><code>6</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_ROT270">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT270">OP_ROT270</a></code></td>
-<td class="colLast"><code>7</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_ROT90">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT90">OP_ROT90</a></code></td>
-<td class="colLast"><code>5</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_TRANSPOSE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSPOSE">OP_TRANSPOSE</a></code></td>
-<td class="colLast"><code>3</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_TRANSVERSE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSVERSE">OP_TRANSVERSE</a></code></td>
-<td class="colLast"><code>4</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OP_VFLIP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OP_VFLIP">OP_VFLIP</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_COPYNONE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_COPYNONE">OPT_COPYNONE</a></code></td>
-<td class="colLast"><code>64</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_CROP">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_CROP">OPT_CROP</a></code></td>
-<td class="colLast"><code>4</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_GRAY">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_GRAY">OPT_GRAY</a></code></td>
-<td class="colLast"><code>8</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_NOOUTPUT">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT">OPT_NOOUTPUT</a></code></td>
-<td class="colLast"><code>16</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_PERFECT">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT">OPT_PERFECT</a></code></td>
-<td class="colLast"><code>1</code></td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_PROGRESSIVE">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PROGRESSIVE">OPT_PROGRESSIVE</a></code></td>
-<td class="colLast"><code>32</code></td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a name="org.libjpegturbo.turbojpeg.TJTransform.OPT_TRIM">
-<!--   -->
-</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
-<td><code><a href="org/libjpegturbo/turbojpeg/TJTransform.html#OPT_TRIM">OPT_TRIM</a></code></td>
-<td class="colLast"><code>2</code></td>
-</tr>
-</tbody>
-</table>
-</li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
-<li><a href="constant-values.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/deprecated-list.html b/src/third_party/libjpeg-turbo/java/doc/deprecated-list.html
deleted file mode 100644
index 31d4e64..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/deprecated-list.html
+++ /dev/null
@@ -1,252 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Deprecated List</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="Deprecated List";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li class="navBarCell1Rev">Deprecated</li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
-<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 title="Deprecated API" class="title">Deprecated API</h1>
-<h2 title="Contents">Contents</h2>
-<ul>
-<li><a href="#field">Deprecated Fields</a></li>
-<li><a href="#method">Deprecated Methods</a></li>
-<li><a href="#constructor">Deprecated Constructors</a></li>
-</ul>
-</div>
-<div class="contentContainer"><a name="field">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<table border="0" cellpadding="3" cellspacing="0" summary="Deprecated Fields table, listing deprecated fields, and an explanation">
-<caption><span>Deprecated Fields</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Field and Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCEMMX">org.libjpegturbo.turbojpeg.TJ.FLAG_FORCEMMX</a></td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE">org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE</a></td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE2">org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE2</a></td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE3">org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE3</a></td>
-</tr>
-</tbody>
-</table>
-</li>
-</ul>
-<a name="method">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<table border="0" cellpadding="3" cellspacing="0" summary="Deprecated Methods table, listing deprecated methods, and an explanation">
-<caption><span>Deprecated Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Method and Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int)">org.libjpegturbo.turbojpeg.TJ.bufSizeYUV(int, int, int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>TJ.bufSizeYUV(int, int, int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20byte[],%20int)">org.libjpegturbo.turbojpeg.TJCompressor.compress(BufferedImage, byte[], int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)"><code>TJCompressor.compress(byte[], int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20int)">org.libjpegturbo.turbojpeg.TJCompressor.compress(BufferedImage, int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)"><code>TJCompressor.compress(int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int)">org.libjpegturbo.turbojpeg.TJDecompressor.decompress(byte[], int, int, int, int, int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJDecompressor.decompress(byte[], int, int, int, int, int, int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(byte[],%20int)">org.libjpegturbo.turbojpeg.TJDecompressor.decompressToYUV(byte[], int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>TJDecompressor.decompressToYUV(YUVImage, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int)">org.libjpegturbo.turbojpeg.TJDecompressor.decompressToYUV(int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)"><code>TJDecompressor.decompressToYUV(int, int, int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20byte[],%20int)">org.libjpegturbo.turbojpeg.TJCompressor.encodeYUV(BufferedImage, byte[], int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)"><code>TJCompressor.encodeYUV(byte[], int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20int)">org.libjpegturbo.turbojpeg.TJCompressor.encodeYUV(BufferedImage, int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>TJCompressor.encodeYUV(int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)">org.libjpegturbo.turbojpeg.TJCompressor.encodeYUV(byte[], int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>TJCompressor.encodeYUV(YUVImage, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int)">org.libjpegturbo.turbojpeg.TJCompressor.encodeYUV(int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>TJCompressor.encodeYUV(int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#setJPEGImage(byte[],%20int)">org.libjpegturbo.turbojpeg.TJDecompressor.setJPEGImage(byte[], int)</a>
-<div class="block"><i>Use <a href="org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)"><code>TJDecompressor.setSourceImage(byte[], int)</code></a> instead.</i></div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int)">org.libjpegturbo.turbojpeg.TJCompressor.setSourceImage(byte[], int, int, int, int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-</tbody>
-</table>
-</li>
-</ul>
-<a name="constructor">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<table border="0" cellpadding="3" cellspacing="0" summary="Deprecated Constructors table, listing deprecated constructors, and an explanation">
-<caption><span>Deprecated Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colOne"><a href="org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int)">org.libjpegturbo.turbojpeg.TJCompressor(byte[], int, int, int, int)</a>
-<div class="block"><i>Use
- <a href="org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor.TJCompressor(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</td>
-</tr>
-</tbody>
-</table>
-</li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li class="navBarCell1Rev">Deprecated</li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
-<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/help-doc.html b/src/third_party/libjpeg-turbo/java/doc/help-doc.html
deleted file mode 100644
index 6645d95..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/help-doc.html
+++ /dev/null
@@ -1,210 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>API Help</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="API Help";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li class="navBarCell1Rev">Help</li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
-<li><a href="help-doc.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 class="title">How This API Document Is Organized</h1>
-<div class="subTitle">This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.</div>
-</div>
-<div class="contentContainer">
-<ul class="blockList">
-<li class="blockList">
-<h2>Package</h2>
-<p>Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:</p>
-<ul>
-<li>Interfaces (italic)</li>
-<li>Classes</li>
-<li>Enums</li>
-<li>Exceptions</li>
-<li>Errors</li>
-<li>Annotation Types</li>
-</ul>
-</li>
-<li class="blockList">
-<h2>Class/Interface</h2>
-<p>Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:</p>
-<ul>
-<li>Class inheritance diagram</li>
-<li>Direct Subclasses</li>
-<li>All Known Subinterfaces</li>
-<li>All Known Implementing Classes</li>
-<li>Class/interface declaration</li>
-<li>Class/interface description</li>
-</ul>
-<ul>
-<li>Nested Class Summary</li>
-<li>Field Summary</li>
-<li>Constructor Summary</li>
-<li>Method Summary</li>
-</ul>
-<ul>
-<li>Field Detail</li>
-<li>Constructor Detail</li>
-<li>Method Detail</li>
-</ul>
-<p>Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</p>
-</li>
-<li class="blockList">
-<h2>Annotation Type</h2>
-<p>Each annotation type has its own separate page with the following sections:</p>
-<ul>
-<li>Annotation Type declaration</li>
-<li>Annotation Type description</li>
-<li>Required Element Summary</li>
-<li>Optional Element Summary</li>
-<li>Element Detail</li>
-</ul>
-</li>
-<li class="blockList">
-<h2>Enum</h2>
-<p>Each enum has its own separate page with the following sections:</p>
-<ul>
-<li>Enum declaration</li>
-<li>Enum description</li>
-<li>Enum Constant Summary</li>
-<li>Enum Constant Detail</li>
-</ul>
-</li>
-<li class="blockList">
-<h2>Tree (Class Hierarchy)</h2>
-<p>There is a <a href="overview-tree.html">Class Hierarchy</a> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.</p>
-<ul>
-<li>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.</li>
-<li>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</li>
-</ul>
-</li>
-<li class="blockList">
-<h2>Deprecated API</h2>
-<p>The <a href="deprecated-list.html">Deprecated API</a> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</p>
-</li>
-<li class="blockList">
-<h2>Index</h2>
-<p>The <a href="index-all.html">Index</a> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</p>
-</li>
-<li class="blockList">
-<h2>Prev/Next</h2>
-<p>These links take you to the next or previous class, interface, package, or related page.</p>
-</li>
-<li class="blockList">
-<h2>Frames/No Frames</h2>
-<p>These links show and hide the HTML frames.  All pages are available with or without frames.</p>
-</li>
-<li class="blockList">
-<h2>All Classes</h2>
-<p>The <a href="allclasses-noframe.html">All Classes</a> link shows all classes and interfaces except non-static nested types.</p>
-</li>
-<li class="blockList">
-<h2>Serialized Form</h2>
-<p>Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.</p>
-</li>
-<li class="blockList">
-<h2>Constant Field Values</h2>
-<p>The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.</p>
-</li>
-</ul>
-<em>This help file applies to API documentation generated using the standard doclet.</em></div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li class="navBarCell1Rev">Help</li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
-<li><a href="help-doc.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/index-all.html b/src/third_party/libjpeg-turbo/java/doc/index-all.html
deleted file mode 100644
index 366c7ea1..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/index-all.html
+++ /dev/null
@@ -1,1029 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Index</title>
-<link rel="stylesheet" type="text/css" href="./stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="Index";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="./org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="./org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="./deprecated-list.html">Deprecated</a></li>
-<li class="navBarCell1Rev">Index</li>
-<li><a href="./help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="./index.html?index-all.html" target="_top">Frames</a></li>
-<li><a href="index-all.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="./allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="contentContainer"><a href="#_B_">B</a>&nbsp;<a href="#_C_">C</a>&nbsp;<a href="#_D_">D</a>&nbsp;<a href="#_E_">E</a>&nbsp;<a href="#_F_">F</a>&nbsp;<a href="#_G_">G</a>&nbsp;<a href="#_H_">H</a>&nbsp;<a href="#_I_">I</a>&nbsp;<a href="#_J_">J</a>&nbsp;<a href="#_N_">N</a>&nbsp;<a href="#_O_">O</a>&nbsp;<a href="#_P_">P</a>&nbsp;<a href="#_S_">S</a>&nbsp;<a href="#_T_">T</a>&nbsp;<a href="#_Y_">Y</a>&nbsp;<a name="_B_">
-<!--   -->
-</a>
-<h2 class="title">B</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#bufSize(int,%20int,%20int)">bufSize(int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the maximum size of the buffer (in bytes) required to hold a JPEG
- image with the given width, height, and level of chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)">bufSizeYUV(int, int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV planar
- image with the given width, height, and level of chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int)">bufSizeYUV(int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>TJ.bufSizeYUV(int, int, int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-</dl>
-<a name="_C_">
-<!--   -->
-</a>
-<h2 class="title">C</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#cf">cf</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Custom filter instance</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#close()">close()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Free the native structures associated with this compressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#close()">close()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Free the native structures associated with this decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)">compress(byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and output a JPEG image to the given destination buffer.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)">compress(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and return a buffer containing a JPEG image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20byte[],%20int)">compress(BufferedImage, byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)"><code>TJCompressor.compress(byte[], int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20int)">compress(BufferedImage, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)"><code>TJCompressor.compress(int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#CS_CMYK">CS_CMYK</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">CMYK colorspace.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#CS_GRAY">CS_GRAY</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Grayscale colorspace.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#CS_RGB">CS_RGB</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">RGB colorspace.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#CS_YCbCr">CS_YCbCr</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">YCbCr colorspace.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#CS_YCCK">CS_YCCK</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">YCCK colorspace.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCustomFilter.html#customFilter(java.nio.ShortBuffer,%20java.awt.Rectangle,%20java.awt.Rectangle,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJTransform)">customFilter(ShortBuffer, Rectangle, Rectangle, int, int, TJTransform)</a></span> - Method in interface org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a></dt>
-<dd>
-<div class="block">A callback function that can be used to modify the DCT coefficients after
- they are losslessly transformed but before they are transcoded to a new
- JPEG image.</div>
-</dd>
-</dl>
-<a name="_D_">
-<!--   -->
-</a>
-<h2 class="title">D</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress(byte[], int, int, int, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int)">decompress(byte[], int, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJDecompressor.decompress(byte[], int, int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int,%20int)">decompress(int, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance and return a buffer containing the decompressed image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress(int[], int, int, int, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(java.awt.image.BufferedImage,%20int)">decompress(BufferedImage, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a decompressed/decoded image to
- the given <code>BufferedImage</code> instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int)">decompress(int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and return a <code>BufferedImage</code>
- instance containing the decompressed/decoded image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)">decompressToYUV(YUVImage, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(byte[],%20int)">decompressToYUV(byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>TJDecompressor.decompressToYUV(YUVImage, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int[],%20int,%20int)">decompressToYUV(int, int[], int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a set of Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the decompressed image planes.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)">decompressToYUV(int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the decompressed image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int)">decompressToYUV(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)"><code>TJDecompressor.decompressToYUV(int, int, int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-</dl>
-<a name="_E_">
-<!--   -->
-</a>
-<h2 class="title">E</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)">encodeYUV(YUVImage, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)">encodeYUV(byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>TJCompressor.encodeYUV(YUVImage, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)">encodeYUV(int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the encoded image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int[],%20int)">encodeYUV(int[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into separate Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the encoded image planes.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int)">encodeYUV(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>TJCompressor.encodeYUV(int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20byte[],%20int)">encodeYUV(BufferedImage, byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)"><code>TJCompressor.encodeYUV(byte[], int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20int)">encodeYUV(BufferedImage, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>TJCompressor.encodeYUV(int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#equals(org.libjpegturbo.turbojpeg.TJScalingFactor)">equals(TJScalingFactor)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Returns true or false, depending on whether this instance and
- <code>other</code> have the same numerator and denominator.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#ERR_FATAL">ERR_FATAL</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The error was fatal and non-recoverable.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#ERR_WARNING">ERR_WARNING</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The error was non-fatal and recoverable, but the image may still be
- corrupt.</div>
-</dd>
-</dl>
-<a name="_F_">
-<!--   -->
-</a>
-<h2 class="title">F</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#finalize()">finalize()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#finalize()">finalize()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_ACCURATEDCT">FLAG_ACCURATEDCT</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Use the most accurate DCT/IDCT algorithm available in the underlying
- codec.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP">FLAG_BOTTOMUP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The uncompressed source/destination image is stored in bottom-up (Windows,
- OpenGL) order, not top-down (X11) order.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTDCT">FLAG_FASTDCT</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Use the fastest DCT/IDCT algorithm available in the underlying codec.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTUPSAMPLE">FLAG_FASTUPSAMPLE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">When decompressing an image that was compressed using chrominance
- subsampling, use the fastest chrominance upsampling algorithm available in
- the underlying codec.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCEMMX">FLAG_FORCEMMX</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span></div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE">FLAG_FORCESSE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span></div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE2">FLAG_FORCESSE2</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span></div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE3">FLAG_FORCESSE3</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span></div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_PROGRESSIVE">FLAG_PROGRESSIVE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Use progressive entropy coding in JPEG images generated by compression and
- transform operations.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING">FLAG_STOPONWARNING</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Immediately discontinue the current compression/decompression/transform
- operation if the underlying codec throws a warning (non-fatal error).</div>
-</dd>
-</dl>
-<a name="_G_">
-<!--   -->
-</a>
-<h2 class="title">G</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getAlphaOffset(int)">getAlphaOffset(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">For the given pixel format, returns the number of bytes that the alpha
- component is offset from the start of the pixel.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getBlueOffset(int)">getBlueOffset(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">For the given pixel format, returns the number of bytes that the blue
- component is offset from the start of the pixel.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getBuf()">getBuf()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the YUV image buffer (if this image is stored in a unified
- buffer rather than separate image planes.)</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getColorspace()">getColorspace()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the colorspace used in the source image (JPEG or YUV) associated
- with this decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#getCompressedSize()">getCompressedSize()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Returns the size of the image (in bytes) generated by the most recent
- compress operation.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#getDenom()">getDenom()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Returns denominator</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#getErrorCode()">getErrorCode()</a></span> - Method in exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>
-<div class="block">Returns a code (one of <a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.ERR_*</code></a>) indicating the severity of the
- last error.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getGreenOffset(int)">getGreenOffset(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">For the given pixel format, returns the number of bytes that the green
- component is offset from the start of the pixel.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getHeight()">getHeight()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the height of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getHeight()">getHeight()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the height of the YUV image (or subregion.)</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGBuf()">getJPEGBuf()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the JPEG image buffer associated with this decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGSize()">getJPEGSize()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the size of the JPEG image (in bytes) associated with this
- decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getMCUHeight(int)">getMCUHeight(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the MCU block height for the given level of chrominance
- subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getMCUWidth(int)">getMCUWidth(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the MCU block width for the given level of chrominance
- subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#getNum()">getNum()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Returns numerator</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getOffsets()">getOffsets()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the offsets (in bytes) of each plane within the planes of a larger
- YUV image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getPad()">getPad()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the line padding used in the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getPixelSize(int)">getPixelSize(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the pixel size (in bytes) for the given pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getPlanes()">getPlanes()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the YUV image planes.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getRedOffset(int)">getRedOffset(int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">For the given pixel format, returns the number of bytes that the red
- component is offset from the start of the pixel.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)">getScaled(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Returns the scaled value of <code>dimension</code>.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledHeight(int,%20int)">getScaledHeight(int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the height of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledWidth(int,%20int)">getScaledWidth(int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the width of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#getScalingFactors()">getScalingFactors()</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns a list of fractional scaling factors that the JPEG decompressor in
- this implementation of TurboJPEG supports.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getSize()">getSize()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the size (in bytes) of the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getStrides()">getStrides()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the number of bytes per line of each plane in the YUV image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getSubsamp()">getSubsamp()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the level of chrominance subsampling used in the source image
- (JPEG or YUV) associated with this decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getSubsamp()">getSubsamp()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the level of chrominance subsampling used in the YUV image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#getTransformedSizes()">getTransformedSizes()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Returns an array containing the sizes of the transformed JPEG images
- generated by the most recent transform operation.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#getWidth()">getWidth()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Returns the width of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#getWidth()">getWidth()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Returns the width of the YUV image (or subregion.)</div>
-</dd>
-</dl>
-<a name="_H_">
-<!--   -->
-</a>
-<h2 class="title">H</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#handle">handle</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#handle">handle</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-</dl>
-<a name="_I_">
-<!--   -->
-</a>
-<h2 class="title">I</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#isOne()">isOne()</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Returns true or false, depending on whether this instance is equal to
- 1/1.</div>
-</dd>
-</dl>
-<a name="_J_">
-<!--   -->
-</a>
-<h2 class="title">J</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBuf">jpegBuf</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBufSize">jpegBufSize</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegColorspace">jpegColorspace</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegHeight">jpegHeight</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegSubsamp">jpegSubsamp</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegWidth">jpegWidth</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-</dl>
-<a name="_N_">
-<!--   -->
-</a>
-<h2 class="title">N</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#NUMCS">NUMCS</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The number of JPEG colorspaces</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#NUMERR">NUMERR</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The number of error codes</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#NUMOP">NUMOP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">The number of lossless transform operations</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#NUMPF">NUMPF</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The number of pixel formats</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#NUMSAMP">NUMSAMP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">The number of chrominance subsampling options</div>
-</dd>
-</dl>
-<a name="_O_">
-<!--   -->
-</a>
-<h2 class="title">O</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#op">op</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Transform operation (one of <code>OP_*</code>)</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_HFLIP">OP_HFLIP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Flip (mirror) image horizontally.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_NONE">OP_NONE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Do not transform the position of the image pixels.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT180">OP_ROT180</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Rotate image 180 degrees.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT270">OP_ROT270</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Rotate image counter-clockwise by 90 degrees.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT90">OP_ROT90</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Rotate image clockwise by 90 degrees.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSPOSE">OP_TRANSPOSE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Transpose image (flip/mirror along upper left to lower right axis).</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSVERSE">OP_TRANSVERSE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Transverse transpose image (flip/mirror along upper right to lower left
- axis).</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OP_VFLIP">OP_VFLIP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Flip (mirror) image vertically.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_COPYNONE">OPT_COPYNONE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will prevent <a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from copying any extra markers (including EXIF
- and ICC profile data) from the source image to the output image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_CROP">OPT_CROP</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will enable lossless cropping.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_GRAY">OPT_GRAY</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will discard the color data in the input image and produce
- a grayscale output image.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT">OPT_NOOUTPUT</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will prevent <a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from outputting a JPEG image for this
- particular transform.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT">OPT_PERFECT</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will cause <a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> to throw an exception if the transform is not
- perfect.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PROGRESSIVE">OPT_PROGRESSIVE</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will enable progressive entropy coding in the output image
- generated by this particular transform.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#OPT_TRIM">OPT_TRIM</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">This option will discard any partial MCU blocks that cannot be
- transformed.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#options">options</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Transform options (bitwise OR of one or more of <code>OPT_*</code>)</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a> - package org.libjpegturbo.turbojpeg</dt>
-<dd>&nbsp;</dd>
-</dl>
-<a name="_P_">
-<!--   -->
-</a>
-<h2 class="title">P</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_ABGR">PF_ABGR</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">ABGR pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_ARGB">PF_ARGB</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">ARGB pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_BGR">PF_BGR</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">BGR pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_BGRA">PF_BGRA</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">BGRA pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_BGRX">PF_BGRX</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">BGRX pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_CMYK">PF_CMYK</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">CMYK pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_GRAY">PF_GRAY</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Grayscale pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_RGB">PF_RGB</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">RGB pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_RGBA">PF_RGBA</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">RGBA pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_RGBX">PF_RGBX</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">RGBX pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_XBGR">PF_XBGR</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">XBGR pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#PF_XRGB">PF_XRGB</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">XRGB pixel format.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#planeHeight(int,%20int,%20int)">planeHeight(int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the plane height of a YUV image plane with the given parameters.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#planeSizeYUV(int,%20int,%20int,%20int,%20int)">planeSizeYUV(int, int, int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV image
- plane with the given parameters.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#planeWidth(int,%20int,%20int)">planeWidth(int, int, int)</a></span> - Static method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Returns the plane width of a YUV image plane with the given parameters.</div>
-</dd>
-</dl>
-<a name="_S_">
-<!--   -->
-</a>
-<h2 class="title">S</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_411">SAMP_411</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">4:1:1 chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_420">SAMP_420</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">4:2:0 chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_422">SAMP_422</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">4:2:2 chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_440">SAMP_440</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">4:4:0 chrominance subsampling.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_444">SAMP_444</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">4:4:4 chrominance subsampling (no chrominance subsampling).</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJ.html#SAMP_GRAY">SAMP_GRAY</a></span> - Static variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></dt>
-<dd>
-<div class="block">Grayscale.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#setBuf(byte[][],%20int[],%20int,%20int[],%20int,%20int)">setBuf(byte[][], int[], int, int[], int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Assign a set of image planes to this <code>YUVImage</code> instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#setBuf(byte[],%20int,%20int,%20int,%20int)">setBuf(byte[], int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Assign a unified image buffer to this <code>YUVImage</code> instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#setJPEGImage(byte[],%20int)">setJPEGImage(byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use <a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)"><code>TJDecompressor.setSourceImage(byte[], int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setJPEGQuality(int)">setJPEGQuality(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Set the JPEG image quality level for subsequent compress operations.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)">setSourceImage(byte[], int, int, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Associate an uncompressed RGB, grayscale, or CMYK source image with this
- compressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int)">setSourceImage(byte[], int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor.setSourceImage(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)">setSourceImage(BufferedImage, int, int, int, int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Associate an uncompressed RGB or grayscale source image with this
- compressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">setSourceImage(YUVImage)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Associate an uncompressed YUV planar source image with this compressor
- instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)">setSourceImage(byte[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Associate the JPEG image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with this decompressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">setSourceImage(YUVImage)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Associate the specified YUV planar source image with this decompressor
- instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#setSubsamp(int)">setSubsamp(int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Set the level of chrominance subsampling for subsequent compress/encode
- operations.</div>
-</dd>
-</dl>
-<a name="_T_">
-<!--   -->
-</a>
-<h2 class="title">T</h2>
-<dl>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJ</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">TurboJPEG utility class (cannot be instantiated)</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJCompressor</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">TurboJPEG compressor</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor()">TJCompressor()</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG compressor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)">TJCompressor(byte[], int, int, int, int, int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int)">TJCompressor(byte[], int, int, int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block"><span class="strong">Deprecated.</span>
-<div class="block"><i>Use
- <a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor.TJCompressor(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)">TJCompressor(BufferedImage, int, int, int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">TJCustomFilter</span></a> - Interface in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">Custom filter callback interface</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJDecompressor</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">TurboJPEG decompressor</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor()">TJDecompressor()</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG decompresssor instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(byte[])">TJDecompressor(byte[])</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(byte[],%20int)">TJDecompressor(byte[], int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(org.libjpegturbo.turbojpeg.YUVImage)">TJDecompressor(YUVImage)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG decompressor instance and associate the YUV planar
- source image stored in <code>yuvImage</code> with the newly created
- instance.</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJException</span></a> - Exception in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#TJException()">TJException()</a></span> - Constructor for exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String,%20java.lang.Throwable)">TJException(String, Throwable)</a></span> - Constructor for exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String)">TJException(String)</a></span> - Constructor for exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String,%20int)">TJException(String, int)</a></span> - Constructor for exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.Throwable)">TJException(Throwable)</a></span> - Constructor for exception org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></dt>
-<dd>&nbsp;</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJScalingFactor</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">Fractional scaling factor</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html#TJScalingFactor(int,%20int)">TJScalingFactor(int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG scaling factor instance.</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransform</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">Lossless transform parameters</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform()">TJTransform()</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Create a new lossless transform instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int,%20int,%20int,%20int,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform(int, int, int, int, int, int, TJCustomFilter)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform(Rectangle, int, int, TJCustomFilter)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></dt>
-<dd>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransformer</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">TurboJPEG lossless transformer</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer()">TJTransformer()</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG lossless transformer instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer(byte[])">TJTransformer(byte[])</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer(byte[],%20int)">TJTransformer(byte[], int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)">transform(byte[][], TJTransform[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance into one or more JPEG images stored in the given destination
- buffers.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJTransformer.html#transform(org.libjpegturbo.turbojpeg.TJTransform[],%20int)">transform(TJTransform[], int)</a></span> - Method in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dt>
-<dd>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance and return an array of <a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor</code></a> instances, each of
- which has a transformed JPEG image associated with it.</div>
-</dd>
-</dl>
-<a name="_Y_">
-<!--   -->
-</a>
-<h2 class="title">Y</h2>
-<dl>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvHeight">yuvHeight</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html#yuvImage">yuvImage</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></dt>
-<dd>&nbsp;</dd>
-<dt><a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">YUVImage</span></a> - Class in <a href="./org/libjpegturbo/turbojpeg/package-summary.html">org.libjpegturbo.turbojpeg</a></dt>
-<dd>
-<div class="block">This class encapsulates a YUV planar image and the metadata
- associated with it.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(int,%20int[],%20int,%20int)">YUVImage(int, int[], int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Create a new <code>YUVImage</code> instance backed by separate image
- planes, and allocate memory for the image planes.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(int,%20int,%20int,%20int)">YUVImage(int, int, int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Create a new <code>YUVImage</code> instance backed by a unified image
- buffer, and allocate memory for the image buffer.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(byte[][],%20int[],%20int,%20int[],%20int,%20int)">YUVImage(byte[][], int[], int, int[], int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Create a new <code>YUVImage</code> instance from a set of existing image
- planes.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(byte[],%20int,%20int,%20int,%20int)">YUVImage(byte[], int, int, int, int)</a></span> - Constructor for class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>
-<div class="block">Create a new <code>YUVImage</code> instance from an existing unified image
- buffer.</div>
-</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvOffsets">yuvOffsets</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvPad">yuvPad</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvPlanes">yuvPlanes</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvStrides">yuvStrides</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvSubsamp">yuvSubsamp</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-<dt><span class="strong"><a href="./org/libjpegturbo/turbojpeg/YUVImage.html#yuvWidth">yuvWidth</a></span> - Variable in class org.libjpegturbo.turbojpeg.<a href="./org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></dt>
-<dd>&nbsp;</dd>
-</dl>
-<a href="#_B_">B</a>&nbsp;<a href="#_C_">C</a>&nbsp;<a href="#_D_">D</a>&nbsp;<a href="#_E_">E</a>&nbsp;<a href="#_F_">F</a>&nbsp;<a href="#_G_">G</a>&nbsp;<a href="#_H_">H</a>&nbsp;<a href="#_I_">I</a>&nbsp;<a href="#_J_">J</a>&nbsp;<a href="#_N_">N</a>&nbsp;<a href="#_O_">O</a>&nbsp;<a href="#_P_">P</a>&nbsp;<a href="#_S_">S</a>&nbsp;<a href="#_T_">T</a>&nbsp;<a href="#_Y_">Y</a>&nbsp;</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="./org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="./org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="./deprecated-list.html">Deprecated</a></li>
-<li class="navBarCell1Rev">Index</li>
-<li><a href="./help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="./index.html?index-all.html" target="_top">Frames</a></li>
-<li><a href="index-all.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="./allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/index.html b/src/third_party/libjpeg-turbo/java/doc/index.html
deleted file mode 100644
index 4e21075..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/index.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Generated Documentation (Untitled)</title>
-<script type="text/javascript">
-    tmpTargetPage = "" + window.location.search;
-    if (tmpTargetPage != "" && tmpTargetPage != "undefined")
-        tmpTargetPage = tmpTargetPage.substring(1);
-    if (tmpTargetPage.indexOf(":") != -1 || (tmpTargetPage != "" && !validURL(tmpTargetPage)))
-        tmpTargetPage = "undefined";
-    targetPage = tmpTargetPage;
-    function validURL(url) {
-        try {
-            url = decodeURIComponent(url);
-        }
-        catch (error) {
-            return false;
-        }
-        var pos = url.indexOf(".html");
-        if (pos == -1 || pos != url.length - 5)
-            return false;
-        var allowNumber = false;
-        var allowSep = false;
-        var seenDot = false;
-        for (var i = 0; i < url.length - 5; i++) {
-            var ch = url.charAt(i);
-            if ('a' <= ch && ch <= 'z' ||
-                    'A' <= ch && ch <= 'Z' ||
-                    ch == '$' ||
-                    ch == '_' ||
-                    ch.charCodeAt(0) > 127) {
-                allowNumber = true;
-                allowSep = true;
-            } else if ('0' <= ch && ch <= '9'
-                    || ch == '-') {
-                if (!allowNumber)
-                     return false;
-            } else if (ch == '/' || ch == '.') {
-                if (!allowSep)
-                    return false;
-                allowNumber = false;
-                allowSep = false;
-                if (ch == '.')
-                     seenDot = true;
-                if (ch == '/' && seenDot)
-                     return false;
-            } else {
-                return false;
-            }
-        }
-        return true;
-    }
-    function loadFrames() {
-        if (targetPage != "" && targetPage != "undefined")
-             top.classFrame.location = top.targetPage;
-    }
-</script>
-</head>
-<frameset cols="20%,80%" title="Documentation frame" onload="top.loadFrames()">
-<frame src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
-<frame src="org/libjpegturbo/turbojpeg/package-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
-<noframes>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<h2>Frame Alert</h2>
-<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="org/libjpegturbo/turbojpeg/package-summary.html">Non-frame version</a>.</p>
-</noframes>
-</frameset>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJ.html
deleted file mode 100644
index 79f9fcf..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJ.html
+++ /dev/null
@@ -1,1356 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJ</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJ";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev Class</li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJ.html" target="_top">Frames</a></li>
-<li><a href="TJ.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJ" class="title">Class TJ</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJ</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<hr>
-<br>
-<pre>public final class <span class="strong">TJ</span>
-extends java.lang.Object</pre>
-<div class="block">TurboJPEG utility class (cannot be instantiated)</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- =========== FIELD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_summary">
-<!--   -->
-</a>
-<h3>Field Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
-<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Field and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_CMYK">CS_CMYK</a></strong></code>
-<div class="block">CMYK colorspace.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_GRAY">CS_GRAY</a></strong></code>
-<div class="block">Grayscale colorspace.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_RGB">CS_RGB</a></strong></code>
-<div class="block">RGB colorspace.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCbCr">CS_YCbCr</a></strong></code>
-<div class="block">YCbCr colorspace.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCCK">CS_YCCK</a></strong></code>
-<div class="block">YCCK colorspace.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#ERR_FATAL">ERR_FATAL</a></strong></code>
-<div class="block">The error was fatal and non-recoverable.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#ERR_WARNING">ERR_WARNING</a></strong></code>
-<div class="block">The error was non-fatal and recoverable, but the image may still be
- corrupt.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_ACCURATEDCT">FLAG_ACCURATEDCT</a></strong></code>
-<div class="block">Use the most accurate DCT/IDCT algorithm available in the underlying
- codec.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP">FLAG_BOTTOMUP</a></strong></code>
-<div class="block">The uncompressed source/destination image is stored in bottom-up (Windows,
- OpenGL) order, not top-down (X11) order.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTDCT">FLAG_FASTDCT</a></strong></code>
-<div class="block">Use the fastest DCT/IDCT algorithm available in the underlying codec.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FASTUPSAMPLE">FLAG_FASTUPSAMPLE</a></strong></code>
-<div class="block">When decompressing an image that was compressed using chrominance
- subsampling, use the fastest chrominance upsampling algorithm available in
- the underlying codec.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCEMMX">FLAG_FORCEMMX</a></strong></code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE">FLAG_FORCESSE</a></strong></code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE2">FLAG_FORCESSE2</a></strong></code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_FORCESSE3">FLAG_FORCESSE3</a></strong></code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_PROGRESSIVE">FLAG_PROGRESSIVE</a></strong></code>
-<div class="block">Use progressive entropy coding in JPEG images generated by compression and
- transform operations.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING">FLAG_STOPONWARNING</a></strong></code>
-<div class="block">Immediately discontinue the current compression/decompression/transform
- operation if the underlying codec throws a warning (non-fatal error).</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#NUMCS">NUMCS</a></strong></code>
-<div class="block">The number of JPEG colorspaces</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#NUMERR">NUMERR</a></strong></code>
-<div class="block">The number of error codes</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#NUMPF">NUMPF</a></strong></code>
-<div class="block">The number of pixel formats</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#NUMSAMP">NUMSAMP</a></strong></code>
-<div class="block">The number of chrominance subsampling options</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_ABGR">PF_ABGR</a></strong></code>
-<div class="block">ABGR pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_ARGB">PF_ARGB</a></strong></code>
-<div class="block">ARGB pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_BGR">PF_BGR</a></strong></code>
-<div class="block">BGR pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_BGRA">PF_BGRA</a></strong></code>
-<div class="block">BGRA pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_BGRX">PF_BGRX</a></strong></code>
-<div class="block">BGRX pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_CMYK">PF_CMYK</a></strong></code>
-<div class="block">CMYK pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_GRAY">PF_GRAY</a></strong></code>
-<div class="block">Grayscale pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB">PF_RGB</a></strong></code>
-<div class="block">RGB pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGBA">PF_RGBA</a></strong></code>
-<div class="block">RGBA pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGBX">PF_RGBX</a></strong></code>
-<div class="block">RGBX pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_XBGR">PF_XBGR</a></strong></code>
-<div class="block">XBGR pixel format.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_XRGB">PF_XRGB</a></strong></code>
-<div class="block">XRGB pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_411">SAMP_411</a></strong></code>
-<div class="block">4:1:1 chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_420">SAMP_420</a></strong></code>
-<div class="block">4:2:0 chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_422">SAMP_422</a></strong></code>
-<div class="block">4:2:2 chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_440">SAMP_440</a></strong></code>
-<div class="block">4:4:0 chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444">SAMP_444</a></strong></code>
-<div class="block">4:4:4 chrominance subsampling (no chrominance subsampling).</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_GRAY">SAMP_GRAY</a></strong></code>
-<div class="block">Grayscale.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSize(int,%20int,%20int)">bufSize</a></strong>(int&nbsp;width,
-       int&nbsp;height,
-       int&nbsp;jpegSubsamp)</code>
-<div class="block">Returns the maximum size of the buffer (in bytes) required to hold a JPEG
- image with the given width, height, and level of chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int)">bufSizeYUV</a></strong>(int&nbsp;width,
-          int&nbsp;height,
-          int&nbsp;subsamp)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>bufSizeYUV(int, int, int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)">bufSizeYUV</a></strong>(int&nbsp;width,
-          int&nbsp;pad,
-          int&nbsp;height,
-          int&nbsp;subsamp)</code>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV planar
- image with the given width, height, and level of chrominance subsampling.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getAlphaOffset(int)">getAlphaOffset</a></strong>(int&nbsp;pixelFormat)</code>
-<div class="block">For the given pixel format, returns the number of bytes that the alpha
- component is offset from the start of the pixel.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getBlueOffset(int)">getBlueOffset</a></strong>(int&nbsp;pixelFormat)</code>
-<div class="block">For the given pixel format, returns the number of bytes that the blue
- component is offset from the start of the pixel.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getGreenOffset(int)">getGreenOffset</a></strong>(int&nbsp;pixelFormat)</code>
-<div class="block">For the given pixel format, returns the number of bytes that the green
- component is offset from the start of the pixel.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUHeight(int)">getMCUHeight</a></strong>(int&nbsp;subsamp)</code>
-<div class="block">Returns the MCU block height for the given level of chrominance
- subsampling.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUWidth(int)">getMCUWidth</a></strong>(int&nbsp;subsamp)</code>
-<div class="block">Returns the MCU block width for the given level of chrominance
- subsampling.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getPixelSize(int)">getPixelSize</a></strong>(int&nbsp;pixelFormat)</code>
-<div class="block">Returns the pixel size (in bytes) for the given pixel format.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getRedOffset(int)">getRedOffset</a></strong>(int&nbsp;pixelFormat)</code>
-<div class="block">For the given pixel format, returns the number of bytes that the red
- component is offset from the start of the pixel.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static <a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a>[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getScalingFactors()">getScalingFactors</a></strong>()</code>
-<div class="block">Returns a list of fractional scaling factors that the JPEG decompressor in
- this implementation of TurboJPEG supports.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#planeHeight(int,%20int,%20int)">planeHeight</a></strong>(int&nbsp;componentID,
-           int&nbsp;height,
-           int&nbsp;subsamp)</code>
-<div class="block">Returns the plane height of a YUV image plane with the given parameters.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#planeSizeYUV(int,%20int,%20int,%20int,%20int)">planeSizeYUV</a></strong>(int&nbsp;componentID,
-            int&nbsp;width,
-            int&nbsp;stride,
-            int&nbsp;height,
-            int&nbsp;subsamp)</code>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV image
- plane with the given parameters.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJ.html#planeWidth(int,%20int,%20int)">planeWidth</a></strong>(int&nbsp;componentID,
-          int&nbsp;width,
-          int&nbsp;subsamp)</code>
-<div class="block">Returns the plane width of a YUV image plane with the given parameters.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ============ FIELD DETAIL =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_detail">
-<!--   -->
-</a>
-<h3>Field Detail</h3>
-<a name="NUMSAMP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>NUMSAMP</h4>
-<pre>public static final&nbsp;int NUMSAMP</pre>
-<div class="block">The number of chrominance subsampling options</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.NUMSAMP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_444">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_444</h4>
-<pre>public static final&nbsp;int SAMP_444</pre>
-<div class="block">4:4:4 chrominance subsampling (no chrominance subsampling).  The JPEG
- or YUV image will contain one chrominance component for every pixel in the
- source image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_444">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_422">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_422</h4>
-<pre>public static final&nbsp;int SAMP_422</pre>
-<div class="block">4:2:2 chrominance subsampling.  The JPEG or YUV image will contain one
- chrominance component for every 2x1 block of pixels in the source image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_422">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_420">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_420</h4>
-<pre>public static final&nbsp;int SAMP_420</pre>
-<div class="block">4:2:0 chrominance subsampling.  The JPEG or YUV image will contain one
- chrominance component for every 2x2 block of pixels in the source image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_420">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_GRAY">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_GRAY</h4>
-<pre>public static final&nbsp;int SAMP_GRAY</pre>
-<div class="block">Grayscale.  The JPEG or YUV image will contain no chrominance components.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_GRAY">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_440">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_440</h4>
-<pre>public static final&nbsp;int SAMP_440</pre>
-<div class="block">4:4:0 chrominance subsampling.  The JPEG or YUV image will contain one
- chrominance component for every 1x2 block of pixels in the source image.
- Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_440">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="SAMP_411">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>SAMP_411</h4>
-<pre>public static final&nbsp;int SAMP_411</pre>
-<div class="block">4:1:1 chrominance subsampling.  The JPEG or YUV image will contain one
- chrominance component for every 4x1 block of pixels in the source image.
- JPEG images compressed with 4:1:1 subsampling will be almost exactly the
- same size as those compressed with 4:2:0 subsampling, and in the
- aggregate, both subsampling methods produce approximately the same
- perceptual quality.  However, 4:1:1 is better able to reproduce sharp
- horizontal features.  Note that 4:1:1 subsampling is not fully accelerated
- in libjpeg-turbo.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.SAMP_411">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="NUMPF">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>NUMPF</h4>
-<pre>public static final&nbsp;int NUMPF</pre>
-<div class="block">The number of pixel formats</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.NUMPF">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_RGB">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_RGB</h4>
-<pre>public static final&nbsp;int PF_RGB</pre>
-<div class="block">RGB pixel format.  The red, green, and blue components in the image are
- stored in 3-byte pixels in the order R, G, B from lowest to highest byte
- address within each pixel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_RGB">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_BGR">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_BGR</h4>
-<pre>public static final&nbsp;int PF_BGR</pre>
-<div class="block">BGR pixel format.  The red, green, and blue components in the image are
- stored in 3-byte pixels in the order B, G, R from lowest to highest byte
- address within each pixel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_BGR">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_RGBX">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_RGBX</h4>
-<pre>public static final&nbsp;int PF_RGBX</pre>
-<div class="block">RGBX pixel format.  The red, green, and blue components in the image are
- stored in 4-byte pixels in the order R, G, B from lowest to highest byte
- address within each pixel.  The X component is ignored when compressing
- and undefined when decompressing.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_RGBX">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_BGRX">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_BGRX</h4>
-<pre>public static final&nbsp;int PF_BGRX</pre>
-<div class="block">BGRX pixel format.  The red, green, and blue components in the image are
- stored in 4-byte pixels in the order B, G, R from lowest to highest byte
- address within each pixel.  The X component is ignored when compressing
- and undefined when decompressing.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_BGRX">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_XBGR">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_XBGR</h4>
-<pre>public static final&nbsp;int PF_XBGR</pre>
-<div class="block">XBGR pixel format.  The red, green, and blue components in the image are
- stored in 4-byte pixels in the order R, G, B from highest to lowest byte
- address within each pixel.  The X component is ignored when compressing
- and undefined when decompressing.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_XBGR">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_XRGB">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_XRGB</h4>
-<pre>public static final&nbsp;int PF_XRGB</pre>
-<div class="block">XRGB pixel format.  The red, green, and blue components in the image are
- stored in 4-byte pixels in the order B, G, R from highest to lowest byte
- address within each pixel.  The X component is ignored when compressing
- and undefined when decompressing.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_XRGB">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_GRAY">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_GRAY</h4>
-<pre>public static final&nbsp;int PF_GRAY</pre>
-<div class="block">Grayscale pixel format.  Each 1-byte pixel represents a luminance
- (brightness) level from 0 to 255.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_GRAY">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_RGBA">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_RGBA</h4>
-<pre>public static final&nbsp;int PF_RGBA</pre>
-<div class="block">RGBA pixel format.  This is the same as <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGBX"><code>PF_RGBX</code></a>, except that when
- decompressing, the X byte is guaranteed to be 0xFF, which can be
- interpreted as an opaque alpha channel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_RGBA">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_BGRA">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_BGRA</h4>
-<pre>public static final&nbsp;int PF_BGRA</pre>
-<div class="block">BGRA pixel format.  This is the same as <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_BGRX"><code>PF_BGRX</code></a>, except that when
- decompressing, the X byte is guaranteed to be 0xFF, which can be
- interpreted as an opaque alpha channel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_BGRA">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_ABGR">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_ABGR</h4>
-<pre>public static final&nbsp;int PF_ABGR</pre>
-<div class="block">ABGR pixel format.  This is the same as <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_XBGR"><code>PF_XBGR</code></a>, except that when
- decompressing, the X byte is guaranteed to be 0xFF, which can be
- interpreted as an opaque alpha channel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_ABGR">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_ARGB">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_ARGB</h4>
-<pre>public static final&nbsp;int PF_ARGB</pre>
-<div class="block">ARGB pixel format.  This is the same as <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_XRGB"><code>PF_XRGB</code></a>, except that when
- decompressing, the X byte is guaranteed to be 0xFF, which can be
- interpreted as an opaque alpha channel.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_ARGB">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="PF_CMYK">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>PF_CMYK</h4>
-<pre>public static final&nbsp;int PF_CMYK</pre>
-<div class="block">CMYK pixel format.  Unlike RGB, which is an additive color model used
- primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive
- color model used primarily for printing.  In the CMYK color model, the
- value of each color component typically corresponds to an amount of cyan,
- magenta, yellow, or black ink that is applied to a white background.  In
- order to convert between CMYK and RGB, it is necessary to use a color
- management system (CMS.)  A CMS will attempt to map colors within the
- printer's gamut to perceptually similar colors in the display's gamut and
- vice versa, but the mapping is typically not 1:1 or reversible, nor can it
- be defined with a simple formula.  Thus, such a conversion is out of scope
- for a codec library.  However, the TurboJPEG API allows for compressing
- CMYK pixels into a YCCK JPEG image (see <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCCK"><code>CS_YCCK</code></a>) and
- decompressing YCCK JPEG images into CMYK pixels.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.PF_CMYK">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="NUMCS">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>NUMCS</h4>
-<pre>public static final&nbsp;int NUMCS</pre>
-<div class="block">The number of JPEG colorspaces</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.NUMCS">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="CS_RGB">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>CS_RGB</h4>
-<pre>public static final&nbsp;int CS_RGB</pre>
-<div class="block">RGB colorspace.  When compressing the JPEG image, the R, G, and B
- components in the source image are reordered into image planes, but no
- colorspace conversion or subsampling is performed.  RGB JPEG images can be
- decompressed to any of the extended RGB pixel formats or grayscale, but
- they cannot be decompressed to YUV images.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.CS_RGB">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="CS_YCbCr">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>CS_YCbCr</h4>
-<pre>public static final&nbsp;int CS_YCbCr</pre>
-<div class="block">YCbCr colorspace.  YCbCr is not an absolute colorspace but rather a
- mathematical transformation of RGB designed solely for storage and
- transmission.  YCbCr images must be converted to RGB before they can
- actually be displayed.  In the YCbCr colorspace, the Y (luminance)
- component represents the black & white portion of the original image, and
- the Cb and Cr (chrominance) components represent the color portion of the
- original image.  Originally, the analog equivalent of this transformation
- allowed the same signal to drive both black & white and color televisions,
- but JPEG images use YCbCr primarily because it allows the color data to be
- optionally subsampled for the purposes of reducing bandwidth or disk
- space.  YCbCr is the most common JPEG colorspace, and YCbCr JPEG images
- can be compressed from and decompressed to any of the extended RGB pixel
- formats or grayscale, or they can be decompressed to YUV planar images.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.CS_YCbCr">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="CS_GRAY">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>CS_GRAY</h4>
-<pre>public static final&nbsp;int CS_GRAY</pre>
-<div class="block">Grayscale colorspace.  The JPEG image retains only the luminance data (Y
- component), and any color data from the source image is discarded.
- Grayscale JPEG images can be compressed from and decompressed to any of
- the extended RGB pixel formats or grayscale, or they can be decompressed
- to YUV planar images.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.CS_GRAY">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="CS_CMYK">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>CS_CMYK</h4>
-<pre>public static final&nbsp;int CS_CMYK</pre>
-<div class="block">CMYK colorspace.  When compressing the JPEG image, the C, M, Y, and K
- components in the source image are reordered into image planes, but no
- colorspace conversion or subsampling is performed.  CMYK JPEG images can
- only be decompressed to CMYK pixels.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.CS_CMYK">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="CS_YCCK">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>CS_YCCK</h4>
-<pre>public static final&nbsp;int CS_YCCK</pre>
-<div class="block">YCCK colorspace.  YCCK (AKA "YCbCrK") is not an absolute colorspace but
- rather a mathematical transformation of CMYK designed solely for storage
- and transmission.  It is to CMYK as YCbCr is to RGB.  CMYK pixels can be
- reversibly transformed into YCCK, and as with YCbCr, the chrominance
- components in the YCCK pixels can be subsampled without incurring major
- perceptual loss.  YCCK JPEG images can only be compressed from and
- decompressed to CMYK pixels.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.CS_YCCK">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_BOTTOMUP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_BOTTOMUP</h4>
-<pre>public static final&nbsp;int FLAG_BOTTOMUP</pre>
-<div class="block">The uncompressed source/destination image is stored in bottom-up (Windows,
- OpenGL) order, not top-down (X11) order.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_BOTTOMUP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FORCEMMX">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FORCEMMX</h4>
-<pre>@Deprecated
-public static final&nbsp;int FLAG_FORCEMMX</pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FORCEMMX">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FORCESSE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FORCESSE</h4>
-<pre>@Deprecated
-public static final&nbsp;int FLAG_FORCESSE</pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FORCESSE2">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FORCESSE2</h4>
-<pre>@Deprecated
-public static final&nbsp;int FLAG_FORCESSE2</pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE2">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FORCESSE3">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FORCESSE3</h4>
-<pre>@Deprecated
-public static final&nbsp;int FLAG_FORCESSE3</pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FORCESSE3">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FASTUPSAMPLE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FASTUPSAMPLE</h4>
-<pre>public static final&nbsp;int FLAG_FASTUPSAMPLE</pre>
-<div class="block">When decompressing an image that was compressed using chrominance
- subsampling, use the fastest chrominance upsampling algorithm available in
- the underlying codec.  The default is to use smooth upsampling, which
- creates a smooth transition between neighboring chrominance components in
- order to reduce upsampling artifacts in the decompressed image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FASTUPSAMPLE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_FASTDCT">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_FASTDCT</h4>
-<pre>public static final&nbsp;int FLAG_FASTDCT</pre>
-<div class="block">Use the fastest DCT/IDCT algorithm available in the underlying codec.  The
- default if this flag is not specified is implementation-specific.  For
- example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast
- algorithm by default when compressing, because this has been shown to have
- only a very slight effect on accuracy, but it uses the accurate algorithm
- when decompressing, because this has been shown to have a larger effect.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_FASTDCT">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_ACCURATEDCT">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_ACCURATEDCT</h4>
-<pre>public static final&nbsp;int FLAG_ACCURATEDCT</pre>
-<div class="block">Use the most accurate DCT/IDCT algorithm available in the underlying
- codec.  The default if this flag is not specified is
- implementation-specific.  For example, the implementation of TurboJPEG for
- libjpeg[-turbo] uses the fast algorithm by default when compressing,
- because this has been shown to have only a very slight effect on accuracy,
- but it uses the accurate algorithm when decompressing, because this has
- been shown to have a larger effect.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_ACCURATEDCT">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_STOPONWARNING">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_STOPONWARNING</h4>
-<pre>public static final&nbsp;int FLAG_STOPONWARNING</pre>
-<div class="block">Immediately discontinue the current compression/decompression/transform
- operation if the underlying codec throws a warning (non-fatal error).  The
- default behavior is to allow the operation to complete unless a fatal
- error is encountered.
- <p>
- NOTE: due to the design of the TurboJPEG Java API, only certain methods
- (specifically, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor.decompress*()</code></a> methods
- with a void return type) will complete and leave the output image in a
- fully recoverable state after a non-fatal error occurs.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_STOPONWARNING">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="FLAG_PROGRESSIVE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>FLAG_PROGRESSIVE</h4>
-<pre>public static final&nbsp;int FLAG_PROGRESSIVE</pre>
-<div class="block">Use progressive entropy coding in JPEG images generated by compression and
- transform operations.  Progressive entropy coding will generally improve
- compression relative to baseline entropy coding (the default), but it will
- reduce compression and decompression performance considerably.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.FLAG_PROGRESSIVE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="NUMERR">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>NUMERR</h4>
-<pre>public static final&nbsp;int NUMERR</pre>
-<div class="block">The number of error codes</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.NUMERR">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="ERR_WARNING">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>ERR_WARNING</h4>
-<pre>public static final&nbsp;int ERR_WARNING</pre>
-<div class="block">The error was non-fatal and recoverable, but the image may still be
- corrupt.
- <p>
- NOTE: due to the design of the TurboJPEG Java API, only certain methods
- (specifically, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor.decompress*()</code></a> methods
- with a void return type) will complete and leave the output image in a
- fully recoverable state after a non-fatal error occurs.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.ERR_WARNING">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="ERR_FATAL">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>ERR_FATAL</h4>
-<pre>public static final&nbsp;int ERR_FATAL</pre>
-<div class="block">The error was fatal and non-recoverable.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJ.ERR_FATAL">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="getMCUWidth(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getMCUWidth</h4>
-<pre>public static&nbsp;int&nbsp;getMCUWidth(int&nbsp;subsamp)</pre>
-<div class="block">Returns the MCU block width for the given level of chrominance
- subsampling.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>subsamp</code> - the level of chrominance subsampling (one of
- <code>SAMP_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the MCU block width for the given level of chrominance
- subsampling.</dd></dl>
-</li>
-</ul>
-<a name="getMCUHeight(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getMCUHeight</h4>
-<pre>public static&nbsp;int&nbsp;getMCUHeight(int&nbsp;subsamp)</pre>
-<div class="block">Returns the MCU block height for the given level of chrominance
- subsampling.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>subsamp</code> - the level of chrominance subsampling (one of
- <code>SAMP_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the MCU block height for the given level of chrominance
- subsampling.</dd></dl>
-</li>
-</ul>
-<a name="getPixelSize(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getPixelSize</h4>
-<pre>public static&nbsp;int&nbsp;getPixelSize(int&nbsp;pixelFormat)</pre>
-<div class="block">Returns the pixel size (in bytes) for the given pixel format.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pixelFormat</code> - the pixel format (one of <code>PF_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the pixel size (in bytes) for the given pixel format.</dd></dl>
-</li>
-</ul>
-<a name="getRedOffset(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getRedOffset</h4>
-<pre>public static&nbsp;int&nbsp;getRedOffset(int&nbsp;pixelFormat)</pre>
-<div class="block">For the given pixel format, returns the number of bytes that the red
- component is offset from the start of the pixel.  For instance, if a pixel
- of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
- then the red component will be
- <code>pixel[TJ.getRedOffset(TJ.PF_BGRX)]</code>.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pixelFormat</code> - the pixel format (one of <code>PF_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the red offset for the given pixel format, or -1 if the pixel
- format does not have a red component.</dd></dl>
-</li>
-</ul>
-<a name="getGreenOffset(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getGreenOffset</h4>
-<pre>public static&nbsp;int&nbsp;getGreenOffset(int&nbsp;pixelFormat)</pre>
-<div class="block">For the given pixel format, returns the number of bytes that the green
- component is offset from the start of the pixel.  For instance, if a pixel
- of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
- then the green component will be
- <code>pixel[TJ.getGreenOffset(TJ.PF_BGRX)]</code>.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pixelFormat</code> - the pixel format (one of <code>PF_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the green offset for the given pixel format, or -1 if the pixel
- format does not have a green component.</dd></dl>
-</li>
-</ul>
-<a name="getBlueOffset(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getBlueOffset</h4>
-<pre>public static&nbsp;int&nbsp;getBlueOffset(int&nbsp;pixelFormat)</pre>
-<div class="block">For the given pixel format, returns the number of bytes that the blue
- component is offset from the start of the pixel.  For instance, if a pixel
- of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
- then the blue component will be
- <code>pixel[TJ.getBlueOffset(TJ.PF_BGRX)]</code>.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pixelFormat</code> - the pixel format (one of <code>PF_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the blue offset for the given pixel format, or -1 if the pixel
- format does not have a blue component.</dd></dl>
-</li>
-</ul>
-<a name="getAlphaOffset(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getAlphaOffset</h4>
-<pre>public static&nbsp;int&nbsp;getAlphaOffset(int&nbsp;pixelFormat)</pre>
-<div class="block">For the given pixel format, returns the number of bytes that the alpha
- component is offset from the start of the pixel.  For instance, if a pixel
- of format <code>TJ.PF_BGRA</code> is stored in <code>char pixel[]</code>,
- then the alpha component will be
- <code>pixel[TJ.getAlphaOffset(TJ.PF_BGRA)]</code>.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pixelFormat</code> - the pixel format (one of <code>PF_*</code>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the alpha offset for the given pixel format, or -1 if the pixel
- format does not have a alpha component.</dd></dl>
-</li>
-</ul>
-<a name="bufSize(int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>bufSize</h4>
-<pre>public static&nbsp;int&nbsp;bufSize(int&nbsp;width,
-          int&nbsp;height,
-          int&nbsp;jpegSubsamp)</pre>
-<div class="block">Returns the maximum size of the buffer (in bytes) required to hold a JPEG
- image with the given width, height, and level of chrominance subsampling.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>width</code> - the width (in pixels) of the JPEG image</dd><dd><code>height</code> - the height (in pixels) of the JPEG image</dd><dd><code>jpegSubsamp</code> - the level of chrominance subsampling to be used when
- generating the JPEG image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.SAMP_*</code></a>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the maximum size of the buffer (in bytes) required to hold a JPEG
- image with the given width, height, and level of chrominance subsampling.</dd></dl>
-</li>
-</ul>
-<a name="bufSizeYUV(int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>bufSizeYUV</h4>
-<pre>public static&nbsp;int&nbsp;bufSizeYUV(int&nbsp;width,
-             int&nbsp;pad,
-             int&nbsp;height,
-             int&nbsp;subsamp)</pre>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV planar
- image with the given width, height, and level of chrominance subsampling.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>width</code> - the width (in pixels) of the YUV image</dd><dd><code>pad</code> - the width of each line in each plane of the image is padded to
- the nearest multiple of this number of bytes (must be a power of 2.)</dd><dd><code>height</code> - the height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.SAMP_*</code></a>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the size of the buffer (in bytes) required to hold a YUV planar
- image with the given width, height, and level of chrominance subsampling.</dd></dl>
-</li>
-</ul>
-<a name="bufSizeYUV(int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>bufSizeYUV</h4>
-<pre>@Deprecated
-public static&nbsp;int&nbsp;bufSizeYUV(int&nbsp;width,
-                        int&nbsp;height,
-                        int&nbsp;subsamp)</pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>bufSizeYUV(int, int, int, int)</code></a> instead.</i></div>
-</li>
-</ul>
-<a name="planeSizeYUV(int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>planeSizeYUV</h4>
-<pre>public static&nbsp;int&nbsp;planeSizeYUV(int&nbsp;componentID,
-               int&nbsp;width,
-               int&nbsp;stride,
-               int&nbsp;height,
-               int&nbsp;subsamp)</pre>
-<div class="block">Returns the size of the buffer (in bytes) required to hold a YUV image
- plane with the given parameters.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>componentID</code> - ID number of the image plane (0 = Y, 1 = U/Cb,
- 2 = V/Cr)</dd><dd><code>width</code> - width (in pixels) of the YUV image.  NOTE: this is the width
- of the whole image, not the plane width.</dd><dd><code>stride</code> - bytes per line in the image plane.</dd><dd><code>height</code> - height (in pixels) of the YUV image.  NOTE: this is the
- height of the whole image, not the plane height.</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.SAMP_*</code></a>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the size of the buffer (in bytes) required to hold a YUV planar
- image with the given parameters.</dd></dl>
-</li>
-</ul>
-<a name="planeWidth(int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>planeWidth</h4>
-<pre>public static&nbsp;int&nbsp;planeWidth(int&nbsp;componentID,
-             int&nbsp;width,
-             int&nbsp;subsamp)</pre>
-<div class="block">Returns the plane width of a YUV image plane with the given parameters.
- Refer to <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> for a description of plane width.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>componentID</code> - ID number of the image plane (0 = Y, 1 = U/Cb,
- 2 = V/Cr)</dd><dd><code>width</code> - width (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV image
- (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.SAMP_*</code></a>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the plane width of a YUV image plane with the given parameters.</dd></dl>
-</li>
-</ul>
-<a name="planeHeight(int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>planeHeight</h4>
-<pre>public static&nbsp;int&nbsp;planeHeight(int&nbsp;componentID,
-              int&nbsp;height,
-              int&nbsp;subsamp)</pre>
-<div class="block">Returns the plane height of a YUV image plane with the given parameters.
- Refer to <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> for a description of plane height.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>componentID</code> - ID number of the image plane (0 = Y, 1 = U/Cb,
- 2 = V/Cr)</dd><dd><code>height</code> - height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV image
- (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.SAMP_*</code></a>)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the plane height of a YUV image plane with the given parameters.</dd></dl>
-</li>
-</ul>
-<a name="getScalingFactors()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>getScalingFactors</h4>
-<pre>public static&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a>[]&nbsp;getScalingFactors()</pre>
-<div class="block">Returns a list of fractional scaling factors that the JPEG decompressor in
- this implementation of TurboJPEG supports.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>a list of fractional scaling factors that the JPEG decompressor in
- this implementation of TurboJPEG supports.</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev Class</li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJ.html" target="_top">Frames</a></li>
-<li><a href="TJ.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html
deleted file mode 100644
index a53f879..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html
+++ /dev/null
@@ -1,926 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJCompressor</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJCompressor";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJCompressor.html" target="_top">Frames</a></li>
-<li><a href="TJCompressor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJCompressor" class="title">Class TJCompressor</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJCompressor</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<dl>
-<dt>All Implemented Interfaces:</dt>
-<dd>java.io.Closeable, java.lang.AutoCloseable</dd>
-</dl>
-<hr>
-<br>
-<pre>public class <span class="strong">TJCompressor</span>
-extends java.lang.Object
-implements java.io.Closeable</pre>
-<div class="block">TurboJPEG compressor</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor()">TJCompressor</a></strong>()</code>
-<div class="block">Create a TurboJPEG compressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)">TJCompressor</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-            int&nbsp;x,
-            int&nbsp;y,
-            int&nbsp;width,
-            int&nbsp;height)</code>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int)">TJCompressor</a></strong>(byte[]&nbsp;srcImage,
-            int&nbsp;width,
-            int&nbsp;pitch,
-            int&nbsp;height,
-            int&nbsp;pixelFormat)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)">TJCompressor</a></strong>(byte[]&nbsp;srcImage,
-            int&nbsp;x,
-            int&nbsp;y,
-            int&nbsp;width,
-            int&nbsp;pitch,
-            int&nbsp;height,
-            int&nbsp;pixelFormat)</code>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#close()">close</a></strong>()</code>
-<div class="block">Free the native structures associated with this compressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20byte[],%20int)">compress</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-        byte[]&nbsp;dstBuf,
-        int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)"><code>compress(byte[], int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(java.awt.image.BufferedImage,%20int)">compress</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-        int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)"><code>compress(int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)">compress</a></strong>(byte[]&nbsp;dstBuf,
-        int&nbsp;flags)</code>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and output a JPEG image to the given destination buffer.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)">compress</a></strong>(int&nbsp;flags)</code>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and return a buffer containing a JPEG image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20byte[],%20int)">encodeYUV</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-         byte[]&nbsp;dstBuf,
-         int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)"><code>encodeYUV(byte[], int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(java.awt.image.BufferedImage,%20int)">encodeYUV</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-         int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>encodeYUV(int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)">encodeYUV</a></strong>(byte[]&nbsp;dstBuf,
-         int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>encodeYUV(YUVImage, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int)">encodeYUV</a></strong>(int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>encodeYUV(int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int[],%20int)">encodeYUV</a></strong>(int[]&nbsp;strides,
-         int&nbsp;flags)</code>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into separate Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the encoded image planes.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)">encodeYUV</a></strong>(int&nbsp;pad,
-         int&nbsp;flags)</code>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the encoded image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)">encodeYUV</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;dstImage,
-         int&nbsp;flags)</code>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#finalize()">finalize</a></strong>()</code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#getCompressedSize()">getCompressedSize</a></strong>()</code>
-<div class="block">Returns the size of the image (in bytes) generated by the most recent
- compress operation.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setJPEGQuality(int)">setJPEGQuality</a></strong>(int&nbsp;quality)</code>
-<div class="block">Set the JPEG image quality level for subsequent compress operations.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)">setSourceImage</a></strong>(java.awt.image.BufferedImage&nbsp;srcImage,
-              int&nbsp;x,
-              int&nbsp;y,
-              int&nbsp;width,
-              int&nbsp;height)</code>
-<div class="block">Associate an uncompressed RGB or grayscale source image with this
- compressor instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int)">setSourceImage</a></strong>(byte[]&nbsp;srcImage,
-              int&nbsp;width,
-              int&nbsp;pitch,
-              int&nbsp;height,
-              int&nbsp;pixelFormat)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)">setSourceImage</a></strong>(byte[]&nbsp;srcImage,
-              int&nbsp;x,
-              int&nbsp;y,
-              int&nbsp;width,
-              int&nbsp;pitch,
-              int&nbsp;height,
-              int&nbsp;pixelFormat)</code>
-<div class="block">Associate an uncompressed RGB, grayscale, or CMYK source image with this
- compressor instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">setSourceImage</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;srcImage)</code>
-<div class="block">Associate an uncompressed YUV planar source image with this compressor
- instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSubsamp(int)">setSubsamp</a></strong>(int&nbsp;newSubsamp)</code>
-<div class="block">Set the level of chrominance subsampling for subsequent compress/encode
- operations.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJCompressor()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJCompressor</h4>
-<pre>public&nbsp;TJCompressor()
-             throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG compressor instance.</div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJCompressor(byte[], int, int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJCompressor</h4>
-<pre>public&nbsp;TJCompressor(byte[]&nbsp;srcImage,
-            int&nbsp;x,
-            int&nbsp;y,
-            int&nbsp;width,
-            int&nbsp;pitch,
-            int&nbsp;height,
-            int&nbsp;pixelFormat)
-             throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>x</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>y</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>width</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>pitch</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>height</code> - see <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> for description</dd><dd><code>pixelFormat</code> - pixel format of the source image (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB"><code>TJ.PF_*</code></a>)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJCompressor(byte[], int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJCompressor</h4>
-<pre>@Deprecated
-public&nbsp;TJCompressor(byte[]&nbsp;srcImage,
-                       int&nbsp;width,
-                       int&nbsp;pitch,
-                       int&nbsp;height,
-                       int&nbsp;pixelFormat)
-             throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#TJCompressor(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>TJCompressor(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJCompressor(java.awt.image.BufferedImage, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJCompressor</h4>
-<pre>public&nbsp;TJCompressor(java.awt.image.BufferedImage&nbsp;srcImage,
-            int&nbsp;x,
-            int&nbsp;y,
-            int&nbsp;width,
-            int&nbsp;height)
-             throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG compressor instance and associate the uncompressed
- source image stored in <code>srcImage</code> with the newly created
- instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> for description</dd><dd><code>x</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> for description</dd><dd><code>y</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> for description</dd><dd><code>width</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> for description</dd><dd><code>height</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> for description</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="setSourceImage(byte[], int, int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>public&nbsp;void&nbsp;setSourceImage(byte[]&nbsp;srcImage,
-                  int&nbsp;x,
-                  int&nbsp;y,
-                  int&nbsp;width,
-                  int&nbsp;pitch,
-                  int&nbsp;height,
-                  int&nbsp;pixelFormat)
-                    throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Associate an uncompressed RGB, grayscale, or CMYK source image with this
- compressor instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - image buffer containing RGB, grayscale, or CMYK pixels to
- be compressed or encoded.  This buffer is not modified.</dd><dd><code>x</code> - x offset (in pixels) of the region in the source image from which
- the JPEG or YUV image should be compressed/encoded</dd><dd><code>y</code> - y offset (in pixels) of the region in the source image from which
- the JPEG or YUV image should be compressed/encoded</dd><dd><code>width</code> - width (in pixels) of the region in the source image from
- which the JPEG or YUV image should be compressed/encoded</dd><dd><code>pitch</code> - bytes per line of the source image.  Normally, this should be
- <code>width * TJ.pixelSize(pixelFormat)</code> if the source image is
- unpadded, but you can use this parameter to, for instance, specify that
- the scanlines in the source image are padded to a 4-byte boundary or to
- compress/encode a JPEG or YUV image from a region of a larger source
- image.  You can also be clever and use this parameter to skip lines, etc.
- Setting this parameter to 0 is the equivalent of setting it to
- <code>width * TJ.pixelSize(pixelFormat)</code>.</dd><dd><code>height</code> - height (in pixels) of the region in the source image from
- which the JPEG or YUV image should be compressed/encoded</dd><dd><code>pixelFormat</code> - pixel format of the source image (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB"><code>TJ.PF_*</code></a>)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setSourceImage(byte[], int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;setSourceImage(byte[]&nbsp;srcImage,
-                             int&nbsp;width,
-                             int&nbsp;pitch,
-                             int&nbsp;height,
-                             int&nbsp;pixelFormat)
-                    throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(byte[],%20int,%20int,%20int,%20int,%20int,%20int)"><code>setSourceImage(byte[], int, int, int, int, int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setSourceImage(java.awt.image.BufferedImage, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>public&nbsp;void&nbsp;setSourceImage(java.awt.image.BufferedImage&nbsp;srcImage,
-                  int&nbsp;x,
-                  int&nbsp;y,
-                  int&nbsp;width,
-                  int&nbsp;height)
-                    throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Associate an uncompressed RGB or grayscale source image with this
- compressor instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - a <code>BufferedImage</code> instance containing RGB or
- grayscale pixels to be compressed or encoded.  This image is not modified.</dd><dd><code>x</code> - x offset (in pixels) of the region in the source image from which
- the JPEG or YUV image should be compressed/encoded</dd><dd><code>y</code> - y offset (in pixels) of the region in the source image from which
- the JPEG or YUV image should be compressed/encoded</dd><dd><code>width</code> - width (in pixels) of the region in the source image from
- which the JPEG or YUV image should be compressed/encoded (0 = use the
- width of the source image)</dd><dd><code>height</code> - height (in pixels) of the region in the source image from
- which the JPEG or YUV image should be compressed/encoded (0 = use the
- height of the source image)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>public&nbsp;void&nbsp;setSourceImage(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;srcImage)
-                    throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Associate an uncompressed YUV planar source image with this compressor
- instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - YUV planar image to be compressed.  This image is not
- modified.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setSubsamp(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSubsamp</h4>
-<pre>public&nbsp;void&nbsp;setSubsamp(int&nbsp;newSubsamp)</pre>
-<div class="block">Set the level of chrominance subsampling for subsequent compress/encode
- operations.  When pixels are converted from RGB to YCbCr (see
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCbCr"><code>TJ.CS_YCbCr</code></a>) or from CMYK to YCCK (see <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCCK"><code>TJ.CS_YCCK</code></a>) as part
- of the JPEG compression process, some of the Cb and Cr (chrominance)
- components can be discarded or averaged together to produce a smaller
- image with little perceptible loss of image clarity (the human eye is more
- sensitive to small changes in brightness than to small changes in color.)
- This is called "chrominance subsampling".
- <p>
- NOTE: This method has no effect when compressing a JPEG image from a YUV
- planar source.  In that case, the level of chrominance subsampling in
- the JPEG image is determined by the source.  Furthermore, this method has
- no effect when encoding to a pre-allocated <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance.  In
- that case, the level of chrominance subsampling is determined by the
- destination.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>newSubsamp</code> - the level of chrominance subsampling to use in
- subsequent compress/encode oeprations (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="setJPEGQuality(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setJPEGQuality</h4>
-<pre>public&nbsp;void&nbsp;setJPEGQuality(int&nbsp;quality)</pre>
-<div class="block">Set the JPEG image quality level for subsequent compress operations.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>quality</code> - the new JPEG image quality level (1 to 100, 1 = worst,
- 100 = best)</dd></dl>
-</li>
-</ul>
-<a name="compress(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>compress</h4>
-<pre>public&nbsp;void&nbsp;compress(byte[]&nbsp;dstBuf,
-            int&nbsp;flags)
-              throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and output a JPEG image to the given destination buffer.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstBuf</code> - buffer that will receive the JPEG image.  Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSize(int,%20int,%20int)"><code>TJ.bufSize(int, int, int)</code></a> to determine the maximum size for this buffer based on
- the source image's width and height and the desired level of chrominance
- subsampling.</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="compress(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>compress</h4>
-<pre>public&nbsp;byte[]&nbsp;compress(int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Compress the uncompressed source image associated with this compressor
- instance and return a buffer containing a JPEG image.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a buffer containing a JPEG image.  The length of this buffer will
- not be equal to the size of the JPEG image.  Use <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#getCompressedSize()"><code>getCompressedSize()</code></a> to obtain the size of the JPEG image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="compress(java.awt.image.BufferedImage, byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>compress</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;compress(java.awt.image.BufferedImage&nbsp;srcImage,
-                       byte[]&nbsp;dstBuf,
-                       int&nbsp;flags)
-              throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(byte[],%20int)"><code>compress(byte[], int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="compress(java.awt.image.BufferedImage, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>compress</h4>
-<pre>@Deprecated
-public&nbsp;byte[]&nbsp;compress(java.awt.image.BufferedImage&nbsp;srcImage,
-                         int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#compress(int)"><code>compress(int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(org.libjpegturbo.turbojpeg.YUVImage, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>public&nbsp;void&nbsp;encodeYUV(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;dstImage,
-             int&nbsp;flags)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.   This method uses the accelerated color
- conversion routines in TurboJPEG's underlying codec but does not execute
- any of the other steps in the JPEG compression process.  Encoding
- CMYK source images to YUV is not supported.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstImage</code> - <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance that will receive the YUV planar
- image</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;encodeYUV(byte[]&nbsp;dstBuf,
-                        int&nbsp;flags)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>encodeYUV(YUVImage, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;encodeYUV(int&nbsp;pad,
-                 int&nbsp;flags)
-                   throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the encoded image.  This method
- uses the accelerated color conversion routines in TurboJPEG's underlying
- codec but does not execute any of the other steps in the JPEG compression
- process.  Encoding CMYK source images to YUV is not supported.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>pad</code> - the width of each line in each plane of the YUV image will be
- padded to the nearest multiple of this number of bytes (must be a power of
- 2.)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a YUV planar image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(int[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;encodeYUV(int[]&nbsp;strides,
-                 int&nbsp;flags)
-                   throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Encode the uncompressed source image associated with this compressor
- instance into separate Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the encoded image planes.  This
- method uses the accelerated color conversion routines in TurboJPEG's
- underlying codec but does not execute any of the other steps in the JPEG
- compression process.  Encoding CMYK source images to YUV is not supported.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>strides</code> - an array of integers, each specifying the number of bytes
- per line in the corresponding plane of the output image.  Setting the
- stride for any plane to 0 is the same as setting it to the component width
- of the plane.  If <code>strides</code> is null, then the strides for all
- planes will be set to their respective component widths.  You can adjust
- the strides in order to add an arbitrary amount of line padding to each
- plane.</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a YUV planar image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>@Deprecated
-public&nbsp;byte[]&nbsp;encodeYUV(int&nbsp;flags)
-                 throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>encodeYUV(int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(java.awt.image.BufferedImage, byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;encodeYUV(java.awt.image.BufferedImage&nbsp;srcImage,
-                        byte[]&nbsp;dstBuf,
-                        int&nbsp;flags)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(byte[],%20int)"><code>encodeYUV(byte[], int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="encodeYUV(java.awt.image.BufferedImage, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>encodeYUV</h4>
-<pre>@Deprecated
-public&nbsp;byte[]&nbsp;encodeYUV(java.awt.image.BufferedImage&nbsp;srcImage,
-                          int&nbsp;flags)
-                 throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#setSourceImage(java.awt.image.BufferedImage,%20int,%20int,%20int,%20int)"><code>setSourceImage(BufferedImage, int, int, int, int)</code></a> and
- <a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html#encodeYUV(int,%20int)"><code>encodeYUV(int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="getCompressedSize()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getCompressedSize</h4>
-<pre>public&nbsp;int&nbsp;getCompressedSize()</pre>
-<div class="block">Returns the size of the image (in bytes) generated by the most recent
- compress operation.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the size of the image (in bytes) generated by the most recent
- compress operation.</dd></dl>
-</li>
-</ul>
-<a name="close()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>close</h4>
-<pre>public&nbsp;void&nbsp;close()
-           throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Free the native structures associated with this compressor instance.</div>
-<dl>
-<dt><strong>Specified by:</strong></dt>
-<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.io.Closeable</code></dd>
-<dt><strong>Specified by:</strong></dt>
-<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.lang.AutoCloseable</code></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="finalize()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>finalize</h4>
-<pre>protected&nbsp;void&nbsp;finalize()
-                 throws java.lang.Throwable</pre>
-<dl>
-<dt><strong>Overrides:</strong></dt>
-<dd><code>finalize</code>&nbsp;in class&nbsp;<code>java.lang.Object</code></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code>java.lang.Throwable</code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJCompressor.html" target="_top">Frames</a></li>
-<li><a href="TJCompressor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
deleted file mode 100644
index 412dcd4..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJCustomFilter</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJCustomFilter";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJCustomFilter.html" target="_top">Frames</a></li>
-<li><a href="TJCustomFilter.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Interface TJCustomFilter" class="title">Interface TJCustomFilter</h2>
-</div>
-<div class="contentContainer">
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<hr>
-<br>
-<pre>public interface <span class="strong">TJCustomFilter</span></pre>
-<div class="block">Custom filter callback interface</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html#customFilter(java.nio.ShortBuffer,%20java.awt.Rectangle,%20java.awt.Rectangle,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJTransform)">customFilter</a></strong>(java.nio.ShortBuffer&nbsp;coeffBuffer,
-            java.awt.Rectangle&nbsp;bufferRegion,
-            java.awt.Rectangle&nbsp;planeRegion,
-            int&nbsp;componentID,
-            int&nbsp;transformID,
-            <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>&nbsp;transform)</code>
-<div class="block">A callback function that can be used to modify the DCT coefficients after
- they are losslessly transformed but before they are transcoded to a new
- JPEG image.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="customFilter(java.nio.ShortBuffer, java.awt.Rectangle, java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJTransform)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>customFilter</h4>
-<pre>void&nbsp;customFilter(java.nio.ShortBuffer&nbsp;coeffBuffer,
-                java.awt.Rectangle&nbsp;bufferRegion,
-                java.awt.Rectangle&nbsp;planeRegion,
-                int&nbsp;componentID,
-                int&nbsp;transformID,
-                <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>&nbsp;transform)
-                  throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">A callback function that can be used to modify the DCT coefficients after
- they are losslessly transformed but before they are transcoded to a new
- JPEG image.  This allows for custom filters or other transformations to be
- applied in the frequency domain.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>coeffBuffer</code> - a buffer containing transformed DCT coefficients.
- (NOTE: this buffer is not guaranteed to be valid once the callback
- returns, so applications wishing to hand off the DCT coefficients to
- another function or library should make a copy of them within the body of
- the callback.)</dd><dd><code>bufferRegion</code> - rectangle containing the width and height of
- <code>coeffBuffer</code> as well as its offset relative to the component
- plane.  TurboJPEG implementations may choose to split each component plane
- into multiple DCT coefficient buffers and call the callback function once
- for each buffer.</dd><dd><code>planeRegion</code> - rectangle containing the width and height of the
- component plane to which <code>coeffBuffer</code> belongs</dd><dd><code>componentID</code> - ID number of the component plane to which
- <code>coeffBuffer</code> belongs (Y, Cb, and Cr have, respectively, ID's
- of 0, 1, and 2 in typical JPEG images.)</dd><dd><code>transformID</code> - ID number of the transformed image to which
- <code>coeffBuffer</code> belongs.  This is the same as the index of the
- transform in the <code>transforms</code> array that was passed to <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a>.</dd><dd><code>transform</code> - a <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><code>TJTransform</code></a> instance that specifies the
- parameters and/or cropping region for this transform</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJCustomFilter.html" target="_top">Frames</a></li>
-<li><a href="TJCustomFilter.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li>Constr&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html
deleted file mode 100644
index b281e32..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html
+++ /dev/null
@@ -1,1255 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJDecompressor</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJDecompressor";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJDecompressor.html" target="_top">Frames</a></li>
-<li><a href="TJDecompressor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJDecompressor" class="title">Class TJDecompressor</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJDecompressor</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<dl>
-<dt>All Implemented Interfaces:</dt>
-<dd>java.io.Closeable, java.lang.AutoCloseable</dd>
-</dl>
-<dl>
-<dt>Direct Known Subclasses:</dt>
-<dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></dd>
-</dl>
-<hr>
-<br>
-<pre>public class <span class="strong">TJDecompressor</span>
-extends java.lang.Object
-implements java.io.Closeable</pre>
-<div class="block">TurboJPEG decompressor</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- =========== FIELD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_summary">
-<!--   -->
-</a>
-<h3>Field Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
-<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Field and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected long</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#handle">handle</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBuf">jpegBuf</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBufSize">jpegBufSize</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegColorspace">jpegColorspace</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegHeight">jpegHeight</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegSubsamp">jpegSubsamp</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegWidth">jpegWidth</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#yuvImage">yuvImage</a></strong></code>&nbsp;</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor()">TJDecompressor</a></strong>()</code>
-<div class="block">Create a TurboJPEG decompresssor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(byte[])">TJDecompressor</a></strong>(byte[]&nbsp;jpegImage)</code>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(byte[],%20int)">TJDecompressor</a></strong>(byte[]&nbsp;jpegImage,
-              int&nbsp;imageSize)</code>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#TJDecompressor(org.libjpegturbo.turbojpeg.YUVImage)">TJDecompressor</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;yuvImage)</code>
-<div class="block">Create a TurboJPEG decompressor instance and associate the YUV planar
- source image stored in <code>yuvImage</code> with the newly created
- instance.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#close()">close</a></strong>()</code>
-<div class="block">Free the native structures associated with this decompressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(java.awt.image.BufferedImage,%20int)">decompress</a></strong>(java.awt.image.BufferedImage&nbsp;dstImage,
-          int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a decompressed/decoded image to
- the given <code>BufferedImage</code> instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int)">decompress</a></strong>(byte[]&nbsp;dstBuf,
-          int&nbsp;desiredWidth,
-          int&nbsp;pitch,
-          int&nbsp;desiredHeight,
-          int&nbsp;pixelFormat,
-          int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress</a></strong>(byte[]&nbsp;dstBuf,
-          int&nbsp;x,
-          int&nbsp;y,
-          int&nbsp;desiredWidth,
-          int&nbsp;pitch,
-          int&nbsp;desiredHeight,
-          int&nbsp;pixelFormat,
-          int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress</a></strong>(int[]&nbsp;dstBuf,
-          int&nbsp;x,
-          int&nbsp;y,
-          int&nbsp;desiredWidth,
-          int&nbsp;stride,
-          int&nbsp;desiredHeight,
-          int&nbsp;pixelFormat,
-          int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>java.awt.image.BufferedImage</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int)">decompress</a></strong>(int&nbsp;desiredWidth,
-          int&nbsp;desiredHeight,
-          int&nbsp;bufferedImageType,
-          int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and return a <code>BufferedImage</code>
- instance containing the decompressed/decoded image.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int,%20int)">decompress</a></strong>(int&nbsp;desiredWidth,
-          int&nbsp;pitch,
-          int&nbsp;desiredHeight,
-          int&nbsp;pixelFormat,
-          int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance and return a buffer containing the decompressed image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(byte[],%20int)">decompressToYUV</a></strong>(byte[]&nbsp;dstBuf,
-               int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>decompressToYUV(YUVImage, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int)">decompressToYUV</a></strong>(int&nbsp;flags)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)"><code>decompressToYUV(int, int, int, int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int[],%20int,%20int)">decompressToYUV</a></strong>(int&nbsp;desiredWidth,
-               int[]&nbsp;strides,
-               int&nbsp;desiredHeight,
-               int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a set of Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the decompressed image planes.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)">decompressToYUV</a></strong>(int&nbsp;desiredWidth,
-               int&nbsp;pad,
-               int&nbsp;desiredHeight,
-               int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the decompressed image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)">decompressToYUV</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;dstImage,
-               int&nbsp;flags)</code>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#finalize()">finalize</a></strong>()</code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getColorspace()">getColorspace</a></strong>()</code>
-<div class="block">Returns the colorspace used in the source image (JPEG or YUV) associated
- with this decompressor instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getHeight()">getHeight</a></strong>()</code>
-<div class="block">Returns the height of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGBuf()">getJPEGBuf</a></strong>()</code>
-<div class="block">Returns the JPEG image buffer associated with this decompressor instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGSize()">getJPEGSize</a></strong>()</code>
-<div class="block">Returns the size of the JPEG image (in bytes) associated with this
- decompressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledHeight(int,%20int)">getScaledHeight</a></strong>(int&nbsp;desiredWidth,
-               int&nbsp;desiredHeight)</code>
-<div class="block">Returns the height of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledWidth(int,%20int)">getScaledWidth</a></strong>(int&nbsp;desiredWidth,
-              int&nbsp;desiredHeight)</code>
-<div class="block">Returns the width of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getSubsamp()">getSubsamp</a></strong>()</code>
-<div class="block">Returns the level of chrominance subsampling used in the source image
- (JPEG or YUV) associated with this decompressor instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getWidth()">getWidth</a></strong>()</code>
-<div class="block">Returns the width of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setJPEGImage(byte[],%20int)">setJPEGImage</a></strong>(byte[]&nbsp;jpegImage,
-            int&nbsp;imageSize)</code>
-<div class="block"><strong>Deprecated.</strong>&nbsp;
-<div class="block"><i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)"><code>setSourceImage(byte[], int)</code></a> instead.</i></div>
-</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)">setSourceImage</a></strong>(byte[]&nbsp;jpegImage,
-              int&nbsp;imageSize)</code>
-<div class="block">Associate the JPEG image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with this decompressor instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">setSourceImage</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;srcImage)</code>
-<div class="block">Associate the specified YUV planar source image with this decompressor
- instance.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ============ FIELD DETAIL =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_detail">
-<!--   -->
-</a>
-<h3>Field Detail</h3>
-<a name="handle">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>handle</h4>
-<pre>protected&nbsp;long handle</pre>
-</li>
-</ul>
-<a name="jpegBuf">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>jpegBuf</h4>
-<pre>protected&nbsp;byte[] jpegBuf</pre>
-</li>
-</ul>
-<a name="jpegBufSize">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>jpegBufSize</h4>
-<pre>protected&nbsp;int jpegBufSize</pre>
-</li>
-</ul>
-<a name="yuvImage">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvImage</h4>
-<pre>protected&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a> yuvImage</pre>
-</li>
-</ul>
-<a name="jpegWidth">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>jpegWidth</h4>
-<pre>protected&nbsp;int jpegWidth</pre>
-</li>
-</ul>
-<a name="jpegHeight">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>jpegHeight</h4>
-<pre>protected&nbsp;int jpegHeight</pre>
-</li>
-</ul>
-<a name="jpegSubsamp">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>jpegSubsamp</h4>
-<pre>protected&nbsp;int jpegSubsamp</pre>
-</li>
-</ul>
-<a name="jpegColorspace">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>jpegColorspace</h4>
-<pre>protected&nbsp;int jpegColorspace</pre>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJDecompressor()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJDecompressor</h4>
-<pre>public&nbsp;TJDecompressor()
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG decompresssor instance.</div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJDecompressor(byte[])">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJDecompressor</h4>
-<pre>public&nbsp;TJDecompressor(byte[]&nbsp;jpegImage)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>jpegImage</code> - JPEG image buffer (size of the JPEG image is assumed to
- be the length of the array.)  This buffer is not modified.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJDecompressor(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJDecompressor</h4>
-<pre>public&nbsp;TJDecompressor(byte[]&nbsp;jpegImage,
-              int&nbsp;imageSize)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG decompressor instance and associate the JPEG source
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>jpegImage</code> - JPEG image buffer.  This buffer is not modified.</dd><dd><code>imageSize</code> - size of the JPEG image (in bytes)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJDecompressor(org.libjpegturbo.turbojpeg.YUVImage)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJDecompressor</h4>
-<pre>public&nbsp;TJDecompressor(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;yuvImage)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG decompressor instance and associate the YUV planar
- source image stored in <code>yuvImage</code> with the newly created
- instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>yuvImage</code> - <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance containing a YUV planar
- image to be decoded.  This image is not modified.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="setSourceImage(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>public&nbsp;void&nbsp;setSourceImage(byte[]&nbsp;jpegImage,
-                  int&nbsp;imageSize)
-                    throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Associate the JPEG image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with this decompressor instance.  This image will
- be used as the source image for subsequent decompress operations.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>jpegImage</code> - JPEG image buffer.  This buffer is not modified.</dd><dd><code>imageSize</code> - size of the JPEG image (in bytes)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setJPEGImage(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setJPEGImage</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;setJPEGImage(byte[]&nbsp;jpegImage,
-                           int&nbsp;imageSize)
-                  throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)"><code>setSourceImage(byte[], int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setSourceImage</h4>
-<pre>public&nbsp;void&nbsp;setSourceImage(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;srcImage)</pre>
-<div class="block">Associate the specified YUV planar source image with this decompressor
- instance.  Subsequent decompress operations will decode this image into an
- RGB or grayscale destination image.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>srcImage</code> - <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance containing a YUV planar image to
- be decoded.  This image is not modified.</dd></dl>
-</li>
-</ul>
-<a name="getWidth()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getWidth</h4>
-<pre>public&nbsp;int&nbsp;getWidth()</pre>
-<div class="block">Returns the width of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the width of the source image (JPEG or YUV) associated with this
- decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getHeight()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getHeight</h4>
-<pre>public&nbsp;int&nbsp;getHeight()</pre>
-<div class="block">Returns the height of the source image (JPEG or YUV) associated with this
- decompressor instance.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the height of the source image (JPEG or YUV) associated with this
- decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getSubsamp()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getSubsamp</h4>
-<pre>public&nbsp;int&nbsp;getSubsamp()</pre>
-<div class="block">Returns the level of chrominance subsampling used in the source image
- (JPEG or YUV) associated with this decompressor instance.  See
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the level of chrominance subsampling used in the source image
- (JPEG or YUV) associated with this decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getColorspace()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getColorspace</h4>
-<pre>public&nbsp;int&nbsp;getColorspace()</pre>
-<div class="block">Returns the colorspace used in the source image (JPEG or YUV) associated
- with this decompressor instance.  See <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_RGB"><code>TJ.CS_*</code></a>.  If the
- source image is YUV, then this always returns <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#CS_YCbCr"><code>TJ.CS_YCbCr</code></a>.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the colorspace used in the source image (JPEG or YUV) associated
- with this decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getJPEGBuf()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getJPEGBuf</h4>
-<pre>public&nbsp;byte[]&nbsp;getJPEGBuf()</pre>
-<div class="block">Returns the JPEG image buffer associated with this decompressor instance.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the JPEG image buffer associated with this decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getJPEGSize()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getJPEGSize</h4>
-<pre>public&nbsp;int&nbsp;getJPEGSize()</pre>
-<div class="block">Returns the size of the JPEG image (in bytes) associated with this
- decompressor instance.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the size of the JPEG image (in bytes) associated with this
- decompressor instance.</dd></dl>
-</li>
-</ul>
-<a name="getScaledWidth(int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getScaledWidth</h4>
-<pre>public&nbsp;int&nbsp;getScaledWidth(int&nbsp;desiredWidth,
-                 int&nbsp;desiredHeight)</pre>
-<div class="block">Returns the width of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - desired width (in pixels) of the decompressed image.
- Setting this to 0 is the same as setting it to the width of the JPEG image
- (in other words, the width will not be considered when determining the
- scaled image size.)</dd><dd><code>desiredHeight</code> - desired height (in pixels) of the decompressed image.
- Setting this to 0 is the same as setting it to the height of the JPEG
- image (in other words, the height will not be considered when determining
- the scaled image size.)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the width of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</dd></dl>
-</li>
-</ul>
-<a name="getScaledHeight(int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getScaledHeight</h4>
-<pre>public&nbsp;int&nbsp;getScaledHeight(int&nbsp;desiredWidth,
-                  int&nbsp;desiredHeight)</pre>
-<div class="block">Returns the height of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - desired width (in pixels) of the decompressed image.
- Setting this to 0 is the same as setting it to the width of the JPEG image
- (in other words, the width will not be considered when determining the
- scaled image size.)</dd><dd><code>desiredHeight</code> - desired height (in pixels) of the decompressed image.
- Setting this to 0 is the same as setting it to the height of the JPEG
- image (in other words, the height will not be considered when determining
- the scaled image size.)</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the height of the largest scaled-down image that the TurboJPEG
- decompressor can generate without exceeding the desired image width and
- height.</dd></dl>
-</li>
-</ul>
-<a name="decompress(byte[], int, int, int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>public&nbsp;void&nbsp;decompress(byte[]&nbsp;dstBuf,
-              int&nbsp;x,
-              int&nbsp;y,
-              int&nbsp;desiredWidth,
-              int&nbsp;pitch,
-              int&nbsp;desiredHeight,
-              int&nbsp;pixelFormat,
-              int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.
- <p>
- NOTE: The output image is fully recoverable if this method throws a
- non-fatal <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><code>TJException</code></a> (unless
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING"><code>TJ.FLAG_STOPONWARNING</code></a> is specified.)</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstBuf</code> - buffer that will receive the decompressed/decoded image.
- If the source image is a JPEG image, then this buffer should normally be
- <code>pitch * scaledHeight</code> bytes in size, where
- <code>scaledHeight</code> can be determined by calling <code>
- scalingFactor.<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)"><code>getScaled</code></a>(jpegHeight)
- </code> with one of the scaling factors returned from <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getScalingFactors()"><code>TJ.getScalingFactors()</code></a> or by calling <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledHeight(int,%20int)"><code>getScaledHeight(int, int)</code></a>.  If the
- source image is a YUV image, then this buffer should normally be
- <code>pitch * height</code> bytes in size, where <code>height</code> is
- the height of the YUV image.  However, the buffer may also be larger than
- the dimensions of the source image, in which case the <code>x</code>,
- <code>y</code>, and <code>pitch</code> parameters can be used to specify
- the region into which the source image should be decompressed/decoded.</dd><dd><code>x</code> - x offset (in pixels) of the region in the destination image into
- which the source image should be decompressed/decoded</dd><dd><code>y</code> - y offset (in pixels) of the region in the destination image into
- which the source image should be decompressed/decoded</dd><dd><code>desiredWidth</code> - If the source image is a JPEG image, then this
- specifies the desired width (in pixels) of the decompressed image (or
- image region.)  If the desired destination image dimensions are different
- than the source image dimensions, then TurboJPEG will use scaling in the
- JPEG decompressor to generate the largest possible image that will fit
- within the desired dimensions.  Setting this to 0 is the same as setting
- it to the width of the JPEG image (in other words, the width will not be
- considered when determining the scaled image size.)  This parameter is
- ignored if the source image is a YUV image.</dd><dd><code>pitch</code> - bytes per line of the destination image.  Normally, this
- should be set to <code>scaledWidth * TJ.pixelSize(pixelFormat)</code> if
- the destination image is unpadded, but you can use this to, for instance,
- pad each line of the destination image to a 4-byte boundary or to
- decompress/decode the source image into a region of a larger image.  NOTE:
- if the source image is a JPEG image, then <code>scaledWidth</code> can be
- determined by calling <code>
- scalingFactor.<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)"><code>getScaled</code></a>(jpegWidth)
- </code> or by calling <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledWidth(int,%20int)"><code>getScaledWidth(int, int)</code></a>.  If the source image is a
- YUV image, then <code>scaledWidth</code> is the width of the YUV image.
- Setting this parameter to 0 is the equivalent of setting it to
- <code>scaledWidth * TJ.pixelSize(pixelFormat)</code>.</dd><dd><code>desiredHeight</code> - If the source image is a JPEG image, then this
- specifies the desired height (in pixels) of the decompressed image (or
- image region.)  If the desired destination image dimensions are different
- than the source image dimensions, then TurboJPEG will use scaling in the
- JPEG decompressor to generate the largest possible image that will fit
- within the desired dimensions.  Setting this to 0 is the same as setting
- it to the height of the JPEG image (in other words, the height will not be
- considered when determining the scaled image size.)  This parameter is
- ignored if the source image is a YUV image.</dd><dd><code>pixelFormat</code> - pixel format of the decompressed/decoded image (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB"><code>TJ.PF_*</code></a>)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompress(byte[], int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;decompress(byte[]&nbsp;dstBuf,
-                         int&nbsp;desiredWidth,
-                         int&nbsp;pitch,
-                         int&nbsp;desiredHeight,
-                         int&nbsp;pixelFormat,
-                         int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompress(int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>public&nbsp;byte[]&nbsp;decompress(int&nbsp;desiredWidth,
-                int&nbsp;pitch,
-                int&nbsp;desiredHeight,
-                int&nbsp;pixelFormat,
-                int&nbsp;flags)
-                  throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance and return a buffer containing the decompressed image.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a>
- for description</dd><dd><code>pitch</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a>
- for description</dd><dd><code>desiredHeight</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a>
- for description</dd><dd><code>pixelFormat</code> - pixel format of the decompressed image (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB"><code>TJ.PF_*</code></a>)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a buffer containing the decompressed image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompressToYUV</h4>
-<pre>public&nbsp;void&nbsp;decompressToYUV(<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;dstImage,
-                   int&nbsp;flags)
-                     throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a YUV planar image and store it in the given
- <code>YUVImage</code> instance.  This method performs JPEG decompression
- but leaves out the color conversion step, so a planar YUV image is
- generated instead of an RGB or grayscale image.  This method cannot be
- used to decompress JPEG source images with the CMYK or YCCK colorspace.
- <p>
- NOTE: The YUV planar output image is fully recoverable if this method
- throws a non-fatal <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><code>TJException</code></a> (unless
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING"><code>TJ.FLAG_STOPONWARNING</code></a> is specified.)</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstImage</code> - <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>YUVImage</code></a> instance that will receive the YUV planar
- image.  The level of subsampling specified in this <code>YUVImage</code>
- instance must match that of the JPEG image, and the width and height
- specified in the <code>YUVImage</code> instance must match one of the
- scaled image sizes that TurboJPEG is capable of generating from the JPEG
- source image.</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompressToYUV(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompressToYUV</h4>
-<pre>@Deprecated
-public&nbsp;void&nbsp;decompressToYUV(byte[]&nbsp;dstBuf,
-                              int&nbsp;flags)
-                     throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)"><code>decompressToYUV(YUVImage, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompressToYUV(int, int[], int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompressToYUV</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;decompressToYUV(int&nbsp;desiredWidth,
-                       int[]&nbsp;strides,
-                       int&nbsp;desiredHeight,
-                       int&nbsp;flags)
-                         throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a set of Y, U (Cb), and V (Cr) image planes and return a
- <code>YUVImage</code> instance containing the decompressed image planes.
- This method performs JPEG decompression but leaves out the color
- conversion step, so a planar YUV image is generated instead of an RGB or
- grayscale image.  This method cannot be used to decompress JPEG source
- images with the CMYK or YCCK colorspace.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - desired width (in pixels) of the YUV image.  If the
- desired image dimensions are different than the dimensions of the JPEG
- image being decompressed, then TurboJPEG will use scaling in the JPEG
- decompressor to generate the largest possible image that will fit within
- the desired dimensions.  Setting this to 0 is the same as setting it to
- the width of the JPEG image (in other words, the width will not be
- considered when determining the scaled image size.)</dd><dd><code>strides</code> - an array of integers, each specifying the number of bytes
- per line in the corresponding plane of the output image.  Setting the
- stride for any plane to 0 is the same as setting it to the scaled
- component width of the plane.  If <tt>strides</tt> is NULL, then the
- strides for all planes will be set to their respective scaled component
- widths.  You can adjust the strides in order to add an arbitrary amount of
- line padding to each plane.</dd><dd><code>desiredHeight</code> - desired height (in pixels) of the YUV image.  If the
- desired image dimensions are different than the dimensions of the JPEG
- image being decompressed, then TurboJPEG will use scaling in the JPEG
- decompressor to generate the largest possible image that will fit within
- the desired dimensions.  Setting this to 0 is the same as setting it to
- the height of the JPEG image (in other words, the height will not be
- considered when determining the scaled image size.)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a YUV planar image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompressToYUV(int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompressToYUV</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a>&nbsp;decompressToYUV(int&nbsp;desiredWidth,
-                       int&nbsp;pad,
-                       int&nbsp;desiredHeight,
-                       int&nbsp;flags)
-                         throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image associated with this decompressor
- instance into a unified YUV planar image buffer and return a
- <code>YUVImage</code> instance containing the decompressed image.  This
- method performs JPEG decompression but leaves out the color conversion
- step, so a planar YUV image is generated instead of an RGB or grayscale
- image.  This method cannot be used to decompress JPEG source images with
- the CMYK or YCCK colorspace.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - desired width (in pixels) of the YUV image.  If the
- desired image dimensions are different than the dimensions of the JPEG
- image being decompressed, then TurboJPEG will use scaling in the JPEG
- decompressor to generate the largest possible image that will fit within
- the desired dimensions.  Setting this to 0 is the same as setting it to
- the width of the JPEG image (in other words, the width will not be
- considered when determining the scaled image size.)</dd><dd><code>pad</code> - the width of each line in each plane of the YUV image will be
- padded to the nearest multiple of this number of bytes (must be a power of
- 2.)</dd><dd><code>desiredHeight</code> - desired height (in pixels) of the YUV image.  If the
- desired image dimensions are different than the dimensions of the JPEG
- image being decompressed, then TurboJPEG will use scaling in the JPEG
- decompressor to generate the largest possible image that will fit within
- the desired dimensions.  Setting this to 0 is the same as setting it to
- the height of the JPEG image (in other words, the height will not be
- considered when determining the scaled image size.)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a YUV planar image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompressToYUV(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompressToYUV</h4>
-<pre>@Deprecated
-public&nbsp;byte[]&nbsp;decompressToYUV(int&nbsp;flags)
-                       throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block"><span class="strong">Deprecated.</span>&nbsp;<i>Use <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)"><code>decompressToYUV(int, int, int, int)</code></a> instead.</i></div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompress(int[], int, int, int, int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>public&nbsp;void&nbsp;decompress(int[]&nbsp;dstBuf,
-              int&nbsp;x,
-              int&nbsp;y,
-              int&nbsp;desiredWidth,
-              int&nbsp;stride,
-              int&nbsp;desiredHeight,
-              int&nbsp;pixelFormat,
-              int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a grayscale, RGB, or CMYK image
- to the given destination buffer.
- <p>
- NOTE: The output image is fully recoverable if this method throws a
- non-fatal <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><code>TJException</code></a> (unless
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING"><code>TJ.FLAG_STOPONWARNING</code></a> is specified.)</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstBuf</code> - buffer that will receive the decompressed/decoded image.
- If the source image is a JPEG image, then this buffer should normally be
- <code>stride * scaledHeight</code> pixels in size, where
- <code>scaledHeight</code> can be determined by calling <code>
- scalingFactor.<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)"><code>getScaled</code></a>(jpegHeight)
- </code> with one of the scaling factors returned from <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getScalingFactors()"><code>TJ.getScalingFactors()</code></a> or by calling <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledHeight(int,%20int)"><code>getScaledHeight(int, int)</code></a>.  If the
- source image is a YUV image, then this buffer should normally be
- <code>stride * height</code> pixels in size, where <code>height</code> is
- the height of the YUV image.  However, the buffer may also be larger than
- the dimensions of the JPEG image, in which case the <code>x</code>,
- <code>y</code>, and <code>stride</code> parameters can be used to specify
- the region into which the source image should be decompressed.</dd><dd><code>x</code> - x offset (in pixels) of the region in the destination image into
- which the source image should be decompressed/decoded</dd><dd><code>y</code> - y offset (in pixels) of the region in the destination image into
- which the source image should be decompressed/decoded</dd><dd><code>desiredWidth</code> - If the source image is a JPEG image, then this
- specifies the desired width (in pixels) of the decompressed image (or
- image region.)  If the desired destination image dimensions are different
- than the source image dimensions, then TurboJPEG will use scaling in the
- JPEG decompressor to generate the largest possible image that will fit
- within the desired dimensions.  Setting this to 0 is the same as setting
- it to the width of the JPEG image (in other words, the width will not be
- considered when determining the scaled image size.)  This parameter is
- ignored if the source image is a YUV image.</dd><dd><code>stride</code> - pixels per line of the destination image.  Normally, this
- should be set to <code>scaledWidth</code>, but you can use this to, for
- instance, decompress the JPEG image into a region of a larger image.
- NOTE: if the source image is a JPEG image, then <code>scaledWidth</code>
- can be determined by calling <code>
- scalingFactor.<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)"><code>getScaled</code></a>(jpegWidth)
- </code> or by calling <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledWidth(int,%20int)"><code>getScaledWidth(int, int)</code></a>.  If the source image is a
- YUV image, then <code>scaledWidth</code> is the width of the YUV image.
- Setting this parameter to 0 is the equivalent of setting it to
- <code>scaledWidth</code>.</dd><dd><code>desiredHeight</code> - If the source image is a JPEG image, then this
- specifies the desired height (in pixels) of the decompressed image (or
- image region.)  If the desired destination image dimensions are different
- than the source image dimensions, then TurboJPEG will use scaling in the
- JPEG decompressor to generate the largest possible image that will fit
- within the desired dimensions.  Setting this to 0 is the same as setting
- it to the height of the JPEG image (in other words, the height will not be
- considered when determining the scaled image size.)  This parameter is
- ignored if the source image is a YUV image.</dd><dd><code>pixelFormat</code> - pixel format of the decompressed image (one of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#PF_RGB"><code>TJ.PF_*</code></a>)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompress(java.awt.image.BufferedImage, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>public&nbsp;void&nbsp;decompress(java.awt.image.BufferedImage&nbsp;dstImage,
-              int&nbsp;flags)
-                throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and output a decompressed/decoded image to
- the given <code>BufferedImage</code> instance.
- <p>
- NOTE: The output image is fully recoverable if this method throws a
- non-fatal <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><code>TJException</code></a> (unless
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_STOPONWARNING"><code>TJ.FLAG_STOPONWARNING</code></a> is specified.)</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstImage</code> - a <code>BufferedImage</code> instance that will receive
- the decompressed/decoded image.  If the source image is a JPEG image, then
- the width and height of the <code>BufferedImage</code> instance must match
- one of the scaled image sizes that TurboJPEG is capable of generating from
- the JPEG image.  If the source image is a YUV image, then the width and
- height of the <code>BufferedImage</code> instance must match the width and
- height of the YUV image.</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="decompress(int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>decompress</h4>
-<pre>public&nbsp;java.awt.image.BufferedImage&nbsp;decompress(int&nbsp;desiredWidth,
-                                      int&nbsp;desiredHeight,
-                                      int&nbsp;bufferedImageType,
-                                      int&nbsp;flags)
-                                        throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Decompress the JPEG source image or decode the YUV source image associated
- with this decompressor instance and return a <code>BufferedImage</code>
- instance containing the decompressed/decoded image.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>desiredWidth</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a> for
- description</dd><dd><code>desiredHeight</code> - see
- <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)"><code>decompress(byte[], int, int, int, int, int, int, int)</code></a> for
- description</dd><dd><code>bufferedImageType</code> - the image type of the <code>BufferedImage</code>
- instance that will be created (for instance,
- <code>BufferedImage.TYPE_INT_RGB</code>)</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>a <code>BufferedImage</code> instance containing the
- decompressed/decoded image.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="close()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>close</h4>
-<pre>public&nbsp;void&nbsp;close()
-           throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Free the native structures associated with this decompressor instance.</div>
-<dl>
-<dt><strong>Specified by:</strong></dt>
-<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.io.Closeable</code></dd>
-<dt><strong>Specified by:</strong></dt>
-<dd><code>close</code>&nbsp;in interface&nbsp;<code>java.lang.AutoCloseable</code></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="finalize()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>finalize</h4>
-<pre>protected&nbsp;void&nbsp;finalize()
-                 throws java.lang.Throwable</pre>
-<dl>
-<dt><strong>Overrides:</strong></dt>
-<dd><code>finalize</code>&nbsp;in class&nbsp;<code>java.lang.Object</code></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code>java.lang.Throwable</code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJDecompressor.html" target="_top">Frames</a></li>
-<li><a href="TJDecompressor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJException.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJException.html
deleted file mode 100644
index 66d73e7..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJException.html
+++ /dev/null
@@ -1,340 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJException</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJException";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJException.html" target="_top">Frames</a></li>
-<li><a href="TJException.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJException" class="title">Class TJException</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>java.lang.Throwable</li>
-<li>
-<ul class="inheritance">
-<li>java.lang.Exception</li>
-<li>
-<ul class="inheritance">
-<li>java.io.IOException</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJException</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<dl>
-<dt>All Implemented Interfaces:</dt>
-<dd>java.io.Serializable</dd>
-</dl>
-<hr>
-<br>
-<pre>public class <span class="strong">TJException</span>
-extends java.io.IOException</pre>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../serialized-form.html#org.libjpegturbo.turbojpeg.TJException">Serialized Form</a></dd></dl>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#TJException()">TJException</a></strong>()</code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String)">TJException</a></strong>(java.lang.String&nbsp;message)</code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String,%20int)">TJException</a></strong>(java.lang.String&nbsp;message,
-           int&nbsp;code)</code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.String,%20java.lang.Throwable)">TJException</a></strong>(java.lang.String&nbsp;message,
-           java.lang.Throwable&nbsp;cause)</code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#TJException(java.lang.Throwable)">TJException</a></strong>(java.lang.Throwable&nbsp;cause)</code>&nbsp;</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJException.html#getErrorCode()">getErrorCode</a></strong>()</code>
-<div class="block">Returns a code (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.ERR_*</code></a>) indicating the severity of the
- last error.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Throwable">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Throwable</h3>
-<code>addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJException()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJException</h4>
-<pre>public&nbsp;TJException()</pre>
-</li>
-</ul>
-<a name="TJException(java.lang.String, java.lang.Throwable)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJException</h4>
-<pre>public&nbsp;TJException(java.lang.String&nbsp;message,
-           java.lang.Throwable&nbsp;cause)</pre>
-</li>
-</ul>
-<a name="TJException(java.lang.String)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJException</h4>
-<pre>public&nbsp;TJException(java.lang.String&nbsp;message)</pre>
-</li>
-</ul>
-<a name="TJException(java.lang.String, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJException</h4>
-<pre>public&nbsp;TJException(java.lang.String&nbsp;message,
-           int&nbsp;code)</pre>
-</li>
-</ul>
-<a name="TJException(java.lang.Throwable)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJException</h4>
-<pre>public&nbsp;TJException(java.lang.Throwable&nbsp;cause)</pre>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="getErrorCode()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>getErrorCode</h4>
-<pre>public&nbsp;int&nbsp;getErrorCode()</pre>
-<div class="block">Returns a code (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.ERR_*</code></a>) indicating the severity of the
- last error.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>a code (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><code>TJ.ERR_*</code></a>) indicating the severity of the
- last error.</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJException.html" target="_top">Frames</a></li>
-<li><a href="TJException.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
deleted file mode 100644
index 4006bac..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html
+++ /dev/null
@@ -1,343 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJScalingFactor</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJScalingFactor";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJScalingFactor.html" target="_top">Frames</a></li>
-<li><a href="TJScalingFactor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJScalingFactor" class="title">Class TJScalingFactor</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJScalingFactor</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<hr>
-<br>
-<pre>public class <span class="strong">TJScalingFactor</span>
-extends java.lang.Object</pre>
-<div class="block">Fractional scaling factor</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#TJScalingFactor(int,%20int)">TJScalingFactor</a></strong>(int&nbsp;num,
-               int&nbsp;denom)</code>
-<div class="block">Create a TurboJPEG scaling factor instance.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>boolean</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#equals(org.libjpegturbo.turbojpeg.TJScalingFactor)">equals</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a>&nbsp;other)</code>
-<div class="block">Returns true or false, depending on whether this instance and
- <code>other</code> have the same numerator and denominator.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getDenom()">getDenom</a></strong>()</code>
-<div class="block">Returns denominator</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getNum()">getNum</a></strong>()</code>
-<div class="block">Returns numerator</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#getScaled(int)">getScaled</a></strong>(int&nbsp;dimension)</code>
-<div class="block">Returns the scaled value of <code>dimension</code>.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>boolean</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html#isOne()">isOne</a></strong>()</code>
-<div class="block">Returns true or false, depending on whether this instance is equal to
- 1/1.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJScalingFactor(int, int)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJScalingFactor</h4>
-<pre>public&nbsp;TJScalingFactor(int&nbsp;num,
-               int&nbsp;denom)</pre>
-<div class="block">Create a TurboJPEG scaling factor instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>num</code> - numerator</dd><dd><code>denom</code> - denominator</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="getNum()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getNum</h4>
-<pre>public&nbsp;int&nbsp;getNum()</pre>
-<div class="block">Returns numerator</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>numerator</dd></dl>
-</li>
-</ul>
-<a name="getDenom()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getDenom</h4>
-<pre>public&nbsp;int&nbsp;getDenom()</pre>
-<div class="block">Returns denominator</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>denominator</dd></dl>
-</li>
-</ul>
-<a name="getScaled(int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getScaled</h4>
-<pre>public&nbsp;int&nbsp;getScaled(int&nbsp;dimension)</pre>
-<div class="block">Returns the scaled value of <code>dimension</code>.  This function
- performs the integer equivalent of
- <code>ceil(dimension * scalingFactor)</code>.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dimension</code> - width or height to multiply by this scaling factor</dd>
-<dt><span class="strong">Returns:</span></dt><dd>the scaled value of <code>dimension</code>.</dd></dl>
-</li>
-</ul>
-<a name="equals(org.libjpegturbo.turbojpeg.TJScalingFactor)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>equals</h4>
-<pre>public&nbsp;boolean&nbsp;equals(<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a>&nbsp;other)</pre>
-<div class="block">Returns true or false, depending on whether this instance and
- <code>other</code> have the same numerator and denominator.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>other</code> - the scaling factor against which to compare this one</dd>
-<dt><span class="strong">Returns:</span></dt><dd>true or false, depending on whether this instance and
- <code>other</code> have the same numerator and denominator.</dd></dl>
-</li>
-</ul>
-<a name="isOne()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>isOne</h4>
-<pre>public&nbsp;boolean&nbsp;isOne()</pre>
-<div class="block">Returns true or false, depending on whether this instance is equal to
- 1/1.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>true or false, depending on whether this instance is equal to
- 1/1.</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJScalingFactor.html" target="_top">Frames</a></li>
-<li><a href="TJScalingFactor.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html
deleted file mode 100644
index 5f22691..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html
+++ /dev/null
@@ -1,751 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJTransform</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJTransform";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJTransform.html" target="_top">Frames</a></li>
-<li><a href="TJTransform.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li><a href="#nested_classes_inherited_from_class_java.awt.geom.Rectangle2D">Nested</a>&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#methods_inherited_from_class_java.awt.Rectangle">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li>Method</li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJTransform" class="title">Class TJTransform</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>java.awt.geom.RectangularShape</li>
-<li>
-<ul class="inheritance">
-<li>java.awt.geom.Rectangle2D</li>
-<li>
-<ul class="inheritance">
-<li>java.awt.Rectangle</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJTransform</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<dl>
-<dt>All Implemented Interfaces:</dt>
-<dd>java.awt.Shape, java.io.Serializable, java.lang.Cloneable</dd>
-</dl>
-<hr>
-<br>
-<pre>public class <span class="strong">TJTransform</span>
-extends java.awt.Rectangle</pre>
-<div class="block">Lossless transform parameters</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../serialized-form.html#org.libjpegturbo.turbojpeg.TJTransform">Serialized Form</a></dd></dl>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- ======== NESTED CLASS SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="nested_class_summary">
-<!--   -->
-</a>
-<h3>Nested Class Summary</h3>
-<ul class="blockList">
-<li class="blockList"><a name="nested_classes_inherited_from_class_java.awt.geom.Rectangle2D">
-<!--   -->
-</a>
-<h3>Nested classes/interfaces inherited from class&nbsp;java.awt.geom.Rectangle2D</h3>
-<code>java.awt.geom.Rectangle2D.Double, java.awt.geom.Rectangle2D.Float</code></li>
-</ul>
-</li>
-</ul>
-<!-- =========== FIELD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_summary">
-<!--   -->
-</a>
-<h3>Field Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
-<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Field and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a></code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#cf">cf</a></strong></code>
-<div class="block">Custom filter instance</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#NUMOP">NUMOP</a></strong></code>
-<div class="block">The number of lossless transform operations</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#op">op</a></strong></code>
-<div class="block">Transform operation (one of <code>OP_*</code>)</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_HFLIP">OP_HFLIP</a></strong></code>
-<div class="block">Flip (mirror) image horizontally.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_NONE">OP_NONE</a></strong></code>
-<div class="block">Do not transform the position of the image pixels.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT180">OP_ROT180</a></strong></code>
-<div class="block">Rotate image 180 degrees.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT270">OP_ROT270</a></strong></code>
-<div class="block">Rotate image counter-clockwise by 90 degrees.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_ROT90">OP_ROT90</a></strong></code>
-<div class="block">Rotate image clockwise by 90 degrees.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSPOSE">OP_TRANSPOSE</a></strong></code>
-<div class="block">Transpose image (flip/mirror along upper left to lower right axis).</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_TRANSVERSE">OP_TRANSVERSE</a></strong></code>
-<div class="block">Transverse transpose image (flip/mirror along upper right to lower left
- axis).</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OP_VFLIP">OP_VFLIP</a></strong></code>
-<div class="block">Flip (mirror) image vertically.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_COPYNONE">OPT_COPYNONE</a></strong></code>
-<div class="block">This option will prevent <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from copying any extra markers (including EXIF
- and ICC profile data) from the source image to the output image.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_CROP">OPT_CROP</a></strong></code>
-<div class="block">This option will enable lossless cropping.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_GRAY">OPT_GRAY</a></strong></code>
-<div class="block">This option will discard the color data in the input image and produce
- a grayscale output image.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_NOOUTPUT">OPT_NOOUTPUT</a></strong></code>
-<div class="block">This option will prevent <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from outputting a JPEG image for this
- particular transform.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT">OPT_PERFECT</a></strong></code>
-<div class="block">This option will cause <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> to throw an exception if the transform is not
- perfect.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PROGRESSIVE">OPT_PROGRESSIVE</a></strong></code>
-<div class="block">This option will enable progressive entropy coding in the output image
- generated by this particular transform.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>static int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_TRIM">OPT_TRIM</a></strong></code>
-<div class="block">This option will discard any partial MCU blocks that cannot be
- transformed.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#options">options</a></strong></code>
-<div class="block">Transform options (bitwise OR of one or more of <code>OPT_*</code>)</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="fields_inherited_from_class_java.awt.Rectangle">
-<!--   -->
-</a>
-<h3>Fields inherited from class&nbsp;java.awt.Rectangle</h3>
-<code>height, width, x, y</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="fields_inherited_from_class_java.awt.geom.Rectangle2D">
-<!--   -->
-</a>
-<h3>Fields inherited from class&nbsp;java.awt.geom.Rectangle2D</h3>
-<code>OUT_BOTTOM, OUT_LEFT, OUT_RIGHT, OUT_TOP</code></li>
-</ul>
-</li>
-</ul>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform()">TJTransform</a></strong>()</code>
-<div class="block">Create a new lossless transform instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int,%20int,%20int,%20int,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform</a></strong>(int&nbsp;x,
-           int&nbsp;y,
-           int&nbsp;w,
-           int&nbsp;h,
-           int&nbsp;op,
-           int&nbsp;options,
-           <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a>&nbsp;cf)</code>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(java.awt.Rectangle,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJCustomFilter)">TJTransform</a></strong>(java.awt.Rectangle&nbsp;r,
-           int&nbsp;op,
-           int&nbsp;options,
-           <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a>&nbsp;cf)</code>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.awt.Rectangle">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.awt.Rectangle</h3>
-<code>add, add, add, contains, contains, contains, contains, createIntersection, createUnion, equals, getBounds, getBounds2D, getHeight, getLocation, getSize, getWidth, getX, getY, grow, inside, intersection, intersects, isEmpty, move, outcode, reshape, resize, setBounds, setBounds, setLocation, setLocation, setRect, setSize, setSize, toString, translate, union</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.awt.geom.Rectangle2D">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.awt.geom.Rectangle2D</h3>
-<code>add, add, add, contains, contains, getPathIterator, getPathIterator, hashCode, intersect, intersects, intersectsLine, intersectsLine, outcode, setFrame, setRect, union</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.awt.geom.RectangularShape">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.awt.geom.RectangularShape</h3>
-<code>clone, contains, contains, getCenterX, getCenterY, getFrame, getMaxX, getMaxY, getMinX, getMinY, intersects, setFrame, setFrame, setFrameFromCenter, setFrameFromCenter, setFrameFromDiagonal, setFrameFromDiagonal</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>finalize, getClass, notify, notifyAll, wait, wait, wait</code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.awt.Shape">
-<!--   -->
-</a>
-<h3>Methods inherited from interface&nbsp;java.awt.Shape</h3>
-<code>contains, contains, contains, contains, getPathIterator, getPathIterator, intersects, intersects</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ============ FIELD DETAIL =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_detail">
-<!--   -->
-</a>
-<h3>Field Detail</h3>
-<a name="NUMOP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>NUMOP</h4>
-<pre>public static final&nbsp;int NUMOP</pre>
-<div class="block">The number of lossless transform operations</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.NUMOP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_NONE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_NONE</h4>
-<pre>public static final&nbsp;int OP_NONE</pre>
-<div class="block">Do not transform the position of the image pixels.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_NONE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_HFLIP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_HFLIP</h4>
-<pre>public static final&nbsp;int OP_HFLIP</pre>
-<div class="block">Flip (mirror) image horizontally.  This transform is imperfect if there
- are any partial MCU blocks on the right edge.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_HFLIP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_VFLIP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_VFLIP</h4>
-<pre>public static final&nbsp;int OP_VFLIP</pre>
-<div class="block">Flip (mirror) image vertically.  This transform is imperfect if there are
- any partial MCU blocks on the bottom edge.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_VFLIP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_TRANSPOSE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_TRANSPOSE</h4>
-<pre>public static final&nbsp;int OP_TRANSPOSE</pre>
-<div class="block">Transpose image (flip/mirror along upper left to lower right axis).  This
- transform is always perfect.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_TRANSPOSE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_TRANSVERSE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_TRANSVERSE</h4>
-<pre>public static final&nbsp;int OP_TRANSVERSE</pre>
-<div class="block">Transverse transpose image (flip/mirror along upper right to lower left
- axis).  This transform is imperfect if there are any partial MCU blocks in
- the image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_TRANSVERSE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_ROT90">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_ROT90</h4>
-<pre>public static final&nbsp;int OP_ROT90</pre>
-<div class="block">Rotate image clockwise by 90 degrees.  This transform is imperfect if
- there are any partial MCU blocks on the bottom edge.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_ROT90">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_ROT180">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_ROT180</h4>
-<pre>public static final&nbsp;int OP_ROT180</pre>
-<div class="block">Rotate image 180 degrees.  This transform is imperfect if there are any
- partial MCU blocks in the image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_ROT180">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OP_ROT270">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OP_ROT270</h4>
-<pre>public static final&nbsp;int OP_ROT270</pre>
-<div class="block">Rotate image counter-clockwise by 90 degrees.  This transform is imperfect
- if there are any partial MCU blocks on the right edge.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#OPT_PERFECT"><code>OPT_PERFECT</code></a>, 
-<a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OP_ROT270">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_PERFECT">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_PERFECT</h4>
-<pre>public static final&nbsp;int OPT_PERFECT</pre>
-<div class="block">This option will cause <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> to throw an exception if the transform is not
- perfect.  Lossless transforms operate on MCU blocks, whose size depends on
- the level of chrominance subsampling used.  If the image's width or height
- is not evenly divisible by the MCU block size (see <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth(int)</code></a>
- and <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight(int)</code></a>), then there will be partial MCU blocks on the
- right and/or bottom edges.   It is not possible to move these partial MCU
- blocks to the top or left of the image, so any transform that would
- require that is "imperfect."  If this option is not specified, then any
- partial MCU blocks that cannot be transformed will be left in place, which
- will create odd-looking strips on the right or bottom edge of the image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_PERFECT">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_TRIM">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_TRIM</h4>
-<pre>public static final&nbsp;int OPT_TRIM</pre>
-<div class="block">This option will discard any partial MCU blocks that cannot be
- transformed.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_TRIM">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_CROP">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_CROP</h4>
-<pre>public static final&nbsp;int OPT_CROP</pre>
-<div class="block">This option will enable lossless cropping.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_CROP">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_GRAY">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_GRAY</h4>
-<pre>public static final&nbsp;int OPT_GRAY</pre>
-<div class="block">This option will discard the color data in the input image and produce
- a grayscale output image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_GRAY">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_NOOUTPUT">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_NOOUTPUT</h4>
-<pre>public static final&nbsp;int OPT_NOOUTPUT</pre>
-<div class="block">This option will prevent <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from outputting a JPEG image for this
- particular transform.  This can be used in conjunction with a custom
- filter to capture the transformed DCT coefficients without transcoding
- them.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_NOOUTPUT">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_PROGRESSIVE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_PROGRESSIVE</h4>
-<pre>public static final&nbsp;int OPT_PROGRESSIVE</pre>
-<div class="block">This option will enable progressive entropy coding in the output image
- generated by this particular transform.  Progressive entropy coding will
- generally improve compression relative to baseline entropy coding (the
- default), but it will reduce compression and decompression performance
- considerably.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_PROGRESSIVE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="OPT_COPYNONE">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>OPT_COPYNONE</h4>
-<pre>public static final&nbsp;int OPT_COPYNONE</pre>
-<div class="block">This option will prevent <a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)"><code>TJTransformer.transform()</code></a> from copying any extra markers (including EXIF
- and ICC profile data) from the source image to the output image.</div>
-<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../../../constant-values.html#org.libjpegturbo.turbojpeg.TJTransform.OPT_COPYNONE">Constant Field Values</a></dd></dl>
-</li>
-</ul>
-<a name="op">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>op</h4>
-<pre>public&nbsp;int op</pre>
-<div class="block">Transform operation (one of <code>OP_*</code>)</div>
-</li>
-</ul>
-<a name="options">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>options</h4>
-<pre>public&nbsp;int options</pre>
-<div class="block">Transform options (bitwise OR of one or more of <code>OPT_*</code>)</div>
-</li>
-</ul>
-<a name="cf">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>cf</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a> cf</pre>
-<div class="block">Custom filter instance</div>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJTransform()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJTransform</h4>
-<pre>public&nbsp;TJTransform()</pre>
-<div class="block">Create a new lossless transform instance.</div>
-</li>
-</ul>
-<a name="TJTransform(int, int, int, int, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJTransform</h4>
-<pre>public&nbsp;TJTransform(int&nbsp;x,
-           int&nbsp;y,
-           int&nbsp;w,
-           int&nbsp;h,
-           int&nbsp;op,
-           int&nbsp;options,
-           <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a>&nbsp;cf)</pre>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>x</code> - the left boundary of the cropping region.  This must be evenly
- divisible by the MCU block width (see <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUWidth(int)"><code>TJ.getMCUWidth(int)</code></a>)</dd><dd><code>y</code> - the upper boundary of the cropping region.  This must be evenly
- divisible by the MCU block height (see <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#getMCUHeight(int)"><code>TJ.getMCUHeight(int)</code></a>)</dd><dd><code>w</code> - the width of the cropping region.  Setting this to 0 is the
- equivalent of setting it to (width of the source JPEG image -
- <code>x</code>).</dd><dd><code>h</code> - the height of the cropping region.  Setting this to 0 is the
- equivalent of setting it to (height of the source JPEG image -
- <code>y</code>).</dd><dd><code>op</code> - one of the transform operations (<code>OP_*</code>)</dd><dd><code>options</code> - the bitwise OR of one or more of the transform options
- (<code>OPT_*</code>)</dd><dd><code>cf</code> - an instance of an object that implements the <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><code>TJCustomFilter</code></a> interface, or null if no custom filter is needed</dd></dl>
-</li>
-</ul>
-<a name="TJTransform(java.awt.Rectangle, int, int, org.libjpegturbo.turbojpeg.TJCustomFilter)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJTransform</h4>
-<pre>public&nbsp;TJTransform(java.awt.Rectangle&nbsp;r,
-           int&nbsp;op,
-           int&nbsp;options,
-           <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a>&nbsp;cf)</pre>
-<div class="block">Create a new lossless transform instance with the given parameters.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>r</code> - a <code>Rectangle</code> instance that specifies the cropping
- region.  See <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html#TJTransform(int,%20int,%20int,%20int,%20int,%20int,%20org.libjpegturbo.turbojpeg.TJCustomFilter)"><code>TJTransform(int, int, int, int, int, int, TJCustomFilter)</code></a> for more
- detail.</dd><dd><code>op</code> - one of the transform operations (<code>OP_*</code>)</dd><dd><code>options</code> - the bitwise OR of one or more of the transform options
- (<code>OPT_*</code>)</dd><dd><code>cf</code> - an instance of an object that implements the <a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><code>TJCustomFilter</code></a> interface, or null if no custom filter is needed</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJTransform.html" target="_top">Frames</a></li>
-<li><a href="TJTransform.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li><a href="#nested_classes_inherited_from_class_java.awt.geom.Rectangle2D">Nested</a>&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#methods_inherited_from_class_java.awt.Rectangle">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li>Method</li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html
deleted file mode 100644
index a30fe30..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html
+++ /dev/null
@@ -1,421 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>TJTransformer</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="TJTransformer";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJTransformer.html" target="_top">Frames</a></li>
-<li><a href="TJTransformer.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#fields_inherited_from_class_org.libjpegturbo.turbojpeg.TJDecompressor">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class TJTransformer" class="title">Class TJTransformer</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">org.libjpegturbo.turbojpeg.TJDecompressor</a></li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.TJTransformer</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<dl>
-<dt>All Implemented Interfaces:</dt>
-<dd>java.io.Closeable, java.lang.AutoCloseable</dd>
-</dl>
-<hr>
-<br>
-<pre>public class <span class="strong">TJTransformer</span>
-extends <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></pre>
-<div class="block">TurboJPEG lossless transformer</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- =========== FIELD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_summary">
-<!--   -->
-</a>
-<h3>Field Summary</h3>
-<ul class="blockList">
-<li class="blockList"><a name="fields_inherited_from_class_org.libjpegturbo.turbojpeg.TJDecompressor">
-<!--   -->
-</a>
-<h3>Fields inherited from class&nbsp;org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></h3>
-<code><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#handle">handle</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBuf">jpegBuf</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegBufSize">jpegBufSize</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegColorspace">jpegColorspace</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegHeight">jpegHeight</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegSubsamp">jpegSubsamp</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#jpegWidth">jpegWidth</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#yuvImage">yuvImage</a></code></li>
-</ul>
-</li>
-</ul>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer()">TJTransformer</a></strong>()</code>
-<div class="block">Create a TurboJPEG lossless transformer instance.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer(byte[])">TJTransformer</a></strong>(byte[]&nbsp;jpegImage)</code>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#TJTransformer(byte[],%20int)">TJTransformer</a></strong>(byte[]&nbsp;jpegImage,
-             int&nbsp;imageSize)</code>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#getTransformedSizes()">getTransformedSizes</a></strong>()</code>
-<div class="block">Returns an array containing the sizes of the transformed JPEG images
- generated by the most recent transform operation.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(byte[][],%20org.libjpegturbo.turbojpeg.TJTransform[],%20int)">transform</a></strong>(byte[][]&nbsp;dstBufs,
-         <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>[]&nbsp;transforms,
-         int&nbsp;flags)</code>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance into one or more JPEG images stored in the given destination
- buffers.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a>[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html#transform(org.libjpegturbo.turbojpeg.TJTransform[],%20int)">transform</a></strong>(<a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>[]&nbsp;transforms,
-         int&nbsp;flags)</code>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance and return an array of <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor</code></a> instances, each of
- which has a transformed JPEG image associated with it.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_org.libjpegturbo.turbojpeg.TJDecompressor">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></h3>
-<code><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#close()">close</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(java.awt.image.BufferedImage,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(byte[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int[],%20int,%20int,%20int,%20int,%20int,%20int,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompress(int,%20int,%20int,%20int,%20int)">decompress</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(byte[],%20int)">decompressToYUV</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int)">decompressToYUV</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int[],%20int,%20int)">decompressToYUV</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(int,%20int,%20int,%20int)">decompressToYUV</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,%20int)">decompressToYUV</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#finalize()">finalize</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getColorspace()">getColorspace</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getHeight()">getHeight</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGBuf()">getJPEGBuf</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getJPEGSize()">getJPEGSize</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledHeight(int,%20int)">getScaledHeight</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getScaledWidth(int,%20int)">getScaledWidth</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getSubsamp()">getSubsamp</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#getWidth()">getWidth</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setJPEGImage(byte[],%20int)">setJPEGImage</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(byte[],%20int)">setSourceImage</a>, <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html#setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)">setSourceImage</a></code></li>
-</ul>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="TJTransformer()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJTransformer</h4>
-<pre>public&nbsp;TJTransformer()
-              throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG lossless transformer instance.</div>
-<dl><dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJTransformer(byte[])">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>TJTransformer</h4>
-<pre>public&nbsp;TJTransformer(byte[]&nbsp;jpegImage)
-              throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image stored in <code>jpegImage</code> with the newly created instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>jpegImage</code> - JPEG image buffer (size of the JPEG image is assumed to
- be the length of the array.)  This buffer is not modified.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="TJTransformer(byte[], int)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>TJTransformer</h4>
-<pre>public&nbsp;TJTransformer(byte[]&nbsp;jpegImage,
-             int&nbsp;imageSize)
-              throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Create a TurboJPEG lossless transformer instance and associate the JPEG
- image of length <code>imageSize</code> bytes stored in
- <code>jpegImage</code> with the newly created instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>jpegImage</code> - JPEG image buffer.  This buffer is not modified.</dd><dd><code>imageSize</code> - size of the JPEG image (in bytes)</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="transform(byte[][], org.libjpegturbo.turbojpeg.TJTransform[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>transform</h4>
-<pre>public&nbsp;void&nbsp;transform(byte[][]&nbsp;dstBufs,
-             <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>[]&nbsp;transforms,
-             int&nbsp;flags)
-               throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance into one or more JPEG images stored in the given destination
- buffers.  Lossless transforms work by moving the raw coefficients from one
- JPEG image structure to another without altering the values of the
- coefficients.  While this is typically faster than decompressing the
- image, transforming it, and re-compressing it, lossless transforms are not
- free.  Each lossless transform requires reading and performing Huffman
- decoding on all of the coefficients in the source image, regardless of the
- size of the destination image.  Thus, this method provides a means of
- generating multiple transformed images from the same source or of applying
- multiple transformations simultaneously, in order to eliminate the need to
- read the source coefficients multiple times.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>dstBufs</code> - an array of image buffers.  <code>dstbufs[i]</code> will
- receive a JPEG image that has been transformed using the parameters in
- <code>transforms[i]</code>.  Use <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSize(int,%20int,%20int)"><code>TJ.bufSize(int, int, int)</code></a> to determine the
- maximum size for each buffer based on the transformed or cropped width and
- height and the level of subsampling used in the source image.</dd><dd><code>transforms</code> - an array of <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><code>TJTransform</code></a> instances, each of
- which specifies the transform parameters and/or cropping region for the
- corresponding transformed output image</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="transform(org.libjpegturbo.turbojpeg.TJTransform[], int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>transform</h4>
-<pre>public&nbsp;<a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a>[]&nbsp;transform(<a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a>[]&nbsp;transforms,
-                         int&nbsp;flags)
-                           throws <a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></pre>
-<div class="block">Losslessly transform the JPEG image associated with this transformer
- instance and return an array of <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor</code></a> instances, each of
- which has a transformed JPEG image associated with it.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>transforms</code> - an array of <a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><code>TJTransform</code></a> instances, each of
- which specifies the transform parameters and/or cropping region for the
- corresponding transformed output image</dd><dd><code>flags</code> - the bitwise OR of one or more of
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#FLAG_BOTTOMUP"><code>TJ.FLAG_*</code></a></dd>
-<dt><span class="strong">Returns:</span></dt><dd>an array of <a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><code>TJDecompressor</code></a> instances, each of
- which has a transformed JPEG image associated with it.</dd>
-<dt><span class="strong">Throws:</span></dt>
-<dd><code><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></code></dd></dl>
-</li>
-</ul>
-<a name="getTransformedSizes()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>getTransformedSizes</h4>
-<pre>public&nbsp;int[]&nbsp;getTransformedSizes()</pre>
-<div class="block">Returns an array containing the sizes of the transformed JPEG images
- generated by the most recent transform operation.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>an array containing the sizes of the transformed JPEG images
- generated by the most recent transform operation.</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Next Class</span></a></li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/TJTransformer.html" target="_top">Frames</a></li>
-<li><a href="TJTransformer.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#fields_inherited_from_class_org.libjpegturbo.turbojpeg.TJDecompressor">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html
deleted file mode 100644
index d4485ed..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html
+++ /dev/null
@@ -1,765 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>YUVImage</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="YUVImage";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li>Next Class</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/YUVImage.html" target="_top">Frames</a></li>
-<li><a href="YUVImage.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<!-- ======== START OF CLASS DATA ======== -->
-<div class="header">
-<div class="subTitle">org.libjpegturbo.turbojpeg</div>
-<h2 title="Class YUVImage" class="title">Class YUVImage</h2>
-</div>
-<div class="contentContainer">
-<ul class="inheritance">
-<li>java.lang.Object</li>
-<li>
-<ul class="inheritance">
-<li>org.libjpegturbo.turbojpeg.YUVImage</li>
-</ul>
-</li>
-</ul>
-<div class="description">
-<ul class="blockList">
-<li class="blockList">
-<hr>
-<br>
-<pre>public class <span class="strong">YUVImage</span>
-extends java.lang.Object</pre>
-<div class="block">This class encapsulates a YUV planar image and the metadata
- associated with it.  The TurboJPEG API allows both the JPEG compression and
- decompression pipelines to be split into stages:  YUV encode, compress from
- YUV, decompress to YUV, and YUV decode.  A <code>YUVImage</code> instance
- serves as the destination image for YUV encode and decompress-to-YUV
- operations and as the source image for compress-from-YUV and YUV decode
- operations.
- <p>
- Technically, the JPEG format uses the YCbCr colorspace (which technically is
- not a "colorspace" but rather a "color transform"), but per the convention
- of the digital video community, the TurboJPEG API uses "YUV" to refer to an
- image format consisting of Y, Cb, and Cr image planes.
- <p>
- Each plane is simply a 2D array of bytes, each byte representing the value
- of one of the components (Y, Cb, or Cr) at a particular location in the
- image.  The width and height of each plane are determined by the image
- width, height, and level of chrominance subsampling.  The luminance plane
- width is the image width padded to the nearest multiple of the horizontal
- subsampling factor (2 in the case of 4:2:0 and 4:2:2, 4 in the case of
- 4:1:1, 1 in the case of 4:4:4 or grayscale.)  Similarly, the luminance plane
- height is the image height padded to the nearest multiple of the vertical
- subsampling factor (2 in the case of 4:2:0 or 4:4:0, 1 in the case of 4:4:4
- or grayscale.)  The chrominance plane width is equal to the luminance plane
- width divided by the horizontal subsampling factor, and the chrominance
- plane height is equal to the luminance plane height divided by the vertical
- subsampling factor.
- <p>
- For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is
- used, then the luminance plane would be 36 x 35 bytes, and each of the
- chrominance planes would be 18 x 35 bytes.  If you specify a line padding of
- 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and
- each of the chrominance planes would be 20 x 35 bytes.</div>
-</li>
-</ul>
-</div>
-<div class="summary">
-<ul class="blockList">
-<li class="blockList">
-<!-- =========== FIELD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_summary">
-<!--   -->
-</a>
-<h3>Field Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
-<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Field and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected long</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#handle">handle</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvHeight">yuvHeight</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected int[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvOffsets">yuvOffsets</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvPad">yuvPad</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected byte[][]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvPlanes">yuvPlanes</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvStrides">yuvStrides</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvSubsamp">yuvSubsamp</a></strong></code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>protected int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#yuvWidth">yuvWidth</a></strong></code>&nbsp;</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ======== CONSTRUCTOR SUMMARY ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_summary">
-<!--   -->
-</a>
-<h3>Constructor Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
-<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colOne" scope="col">Constructor and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(byte[][],%20int[],%20int,%20int[],%20int,%20int)">YUVImage</a></strong>(byte[][]&nbsp;planes,
-        int[]&nbsp;offsets,
-        int&nbsp;width,
-        int[]&nbsp;strides,
-        int&nbsp;height,
-        int&nbsp;subsamp)</code>
-<div class="block">Create a new <code>YUVImage</code> instance from a set of existing image
- planes.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(byte[],%20int,%20int,%20int,%20int)">YUVImage</a></strong>(byte[]&nbsp;yuvImage,
-        int&nbsp;width,
-        int&nbsp;pad,
-        int&nbsp;height,
-        int&nbsp;subsamp)</code>
-<div class="block">Create a new <code>YUVImage</code> instance from an existing unified image
- buffer.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(int,%20int[],%20int,%20int)">YUVImage</a></strong>(int&nbsp;width,
-        int[]&nbsp;strides,
-        int&nbsp;height,
-        int&nbsp;subsamp)</code>
-<div class="block">Create a new <code>YUVImage</code> instance backed by separate image
- planes, and allocate memory for the image planes.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colOne"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#YUVImage(int,%20int,%20int,%20int)">YUVImage</a></strong>(int&nbsp;width,
-        int&nbsp;pad,
-        int&nbsp;height,
-        int&nbsp;subsamp)</code>
-<div class="block">Create a new <code>YUVImage</code> instance backed by a unified image
- buffer, and allocate memory for the image buffer.</div>
-</td>
-</tr>
-</table>
-</li>
-</ul>
-<!-- ========== METHOD SUMMARY =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_summary">
-<!--   -->
-</a>
-<h3>Method Summary</h3>
-<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
-<caption><span>Methods</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Modifier and Type</th>
-<th class="colLast" scope="col">Method and Description</th>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getBuf()">getBuf</a></strong>()</code>
-<div class="block">Returns the YUV image buffer (if this image is stored in a unified
- buffer rather than separate image planes.)</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getHeight()">getHeight</a></strong>()</code>
-<div class="block">Returns the height of the YUV image (or subregion.)</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getOffsets()">getOffsets</a></strong>()</code>
-<div class="block">Returns the offsets (in bytes) of each plane within the planes of a larger
- YUV image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getPad()">getPad</a></strong>()</code>
-<div class="block">Returns the line padding used in the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>byte[][]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getPlanes()">getPlanes</a></strong>()</code>
-<div class="block">Returns the YUV image planes.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getSize()">getSize</a></strong>()</code>
-<div class="block">Returns the size (in bytes) of the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int[]</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getStrides()">getStrides</a></strong>()</code>
-<div class="block">Returns the number of bytes per line of each plane in the YUV image.</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getSubsamp()">getSubsamp</a></strong>()</code>
-<div class="block">Returns the level of chrominance subsampling used in the YUV image.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>int</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#getWidth()">getWidth</a></strong>()</code>
-<div class="block">Returns the width of the YUV image (or subregion.)</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#setBuf(byte[][],%20int[],%20int,%20int[],%20int,%20int)">setBuf</a></strong>(byte[][]&nbsp;planes,
-      int[]&nbsp;offsets,
-      int&nbsp;width,
-      int[]&nbsp;strides,
-      int&nbsp;height,
-      int&nbsp;subsamp)</code>
-<div class="block">Assign a set of image planes to this <code>YUVImage</code> instance.</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><strong><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html#setBuf(byte[],%20int,%20int,%20int,%20int)">setBuf</a></strong>(byte[]&nbsp;yuvImage,
-      int&nbsp;width,
-      int&nbsp;pad,
-      int&nbsp;height,
-      int&nbsp;subsamp)</code>
-<div class="block">Assign a unified image buffer to this <code>YUVImage</code> instance.</div>
-</td>
-</tr>
-</table>
-<ul class="blockList">
-<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
-<!--   -->
-</a>
-<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
-<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="details">
-<ul class="blockList">
-<li class="blockList">
-<!-- ============ FIELD DETAIL =========== -->
-<ul class="blockList">
-<li class="blockList"><a name="field_detail">
-<!--   -->
-</a>
-<h3>Field Detail</h3>
-<a name="handle">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>handle</h4>
-<pre>protected&nbsp;long handle</pre>
-</li>
-</ul>
-<a name="yuvPlanes">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvPlanes</h4>
-<pre>protected&nbsp;byte[][] yuvPlanes</pre>
-</li>
-</ul>
-<a name="yuvOffsets">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvOffsets</h4>
-<pre>protected&nbsp;int[] yuvOffsets</pre>
-</li>
-</ul>
-<a name="yuvStrides">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvStrides</h4>
-<pre>protected&nbsp;int[] yuvStrides</pre>
-</li>
-</ul>
-<a name="yuvPad">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvPad</h4>
-<pre>protected&nbsp;int yuvPad</pre>
-</li>
-</ul>
-<a name="yuvWidth">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvWidth</h4>
-<pre>protected&nbsp;int yuvWidth</pre>
-</li>
-</ul>
-<a name="yuvHeight">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>yuvHeight</h4>
-<pre>protected&nbsp;int yuvHeight</pre>
-</li>
-</ul>
-<a name="yuvSubsamp">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>yuvSubsamp</h4>
-<pre>protected&nbsp;int yuvSubsamp</pre>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ========= CONSTRUCTOR DETAIL ======== -->
-<ul class="blockList">
-<li class="blockList"><a name="constructor_detail">
-<!--   -->
-</a>
-<h3>Constructor Detail</h3>
-<a name="YUVImage(int, int[], int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>YUVImage</h4>
-<pre>public&nbsp;YUVImage(int&nbsp;width,
-        int[]&nbsp;strides,
-        int&nbsp;height,
-        int&nbsp;subsamp)</pre>
-<div class="block">Create a new <code>YUVImage</code> instance backed by separate image
- planes, and allocate memory for the image planes.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>width</code> - width (in pixels) of the YUV image</dd><dd><code>strides</code> - an array of integers, each specifying the number of bytes
- per line in the corresponding plane of the YUV image.  Setting the stride
- for any plane to 0 is the same as setting it to the plane width (see
- <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>above</code></a>.)  If <code>strides</code> is null, then the
- strides for all planes will be set to their respective plane widths.  When
- using this constructor, the stride for each plane must be equal to or
- greater than the plane width.</dd><dd><code>height</code> - height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling to be used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="YUVImage(int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>YUVImage</h4>
-<pre>public&nbsp;YUVImage(int&nbsp;width,
-        int&nbsp;pad,
-        int&nbsp;height,
-        int&nbsp;subsamp)</pre>
-<div class="block">Create a new <code>YUVImage</code> instance backed by a unified image
- buffer, and allocate memory for the image buffer.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>width</code> - width (in pixels) of the YUV image</dd><dd><code>pad</code> - Each line of each plane in the YUV image buffer will be padded
- to this number of bytes (must be a power of 2.)</dd><dd><code>height</code> - height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling to be used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="YUVImage(byte[][], int[], int, int[], int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>YUVImage</h4>
-<pre>public&nbsp;YUVImage(byte[][]&nbsp;planes,
-        int[]&nbsp;offsets,
-        int&nbsp;width,
-        int[]&nbsp;strides,
-        int&nbsp;height,
-        int&nbsp;subsamp)</pre>
-<div class="block">Create a new <code>YUVImage</code> instance from a set of existing image
- planes.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>planes</code> - an array of buffers representing the Y, U (Cb), and V (Cr)
- image planes (or just the Y plane, if the image is grayscale.)   These
- planes can be contiguous or non-contiguous in memory.  Plane
- <code>i</code> should be at least <code>offsets[i] +
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#planeSizeYUV(int,%20int,%20int,%20int,%20int)"><code>TJ.planeSizeYUV</code></a>(i, width, strides[i], height, subsamp)</code>
- bytes in size.</dd><dd><code>offsets</code> - If this <code>YUVImage</code> instance represents a
- subregion of a larger image, then <code>offsets[i]</code> specifies the
- offset (in bytes) of the subregion within plane <code>i</code> of the
- larger image.  Setting this to null is the same as setting the offsets for
- all planes to 0.</dd><dd><code>width</code> - width (in pixels) of the new YUV image (or subregion)</dd><dd><code>strides</code> - an array of integers, each specifying the number of bytes
- per line in the corresponding plane of the YUV image.  Setting the stride
- for any plane to 0 is the same as setting it to the plane width (see
- <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>above</code></a>.)  If <code>strides</code> is null, then the
- strides for all planes will be set to their respective plane widths.  You
- can adjust the strides in order to add an arbitrary amount of line padding
- to each plane or to specify that this <code>YUVImage</code> instance is a
- subregion of a larger image (in which case, <code>strides[i]</code> should
- be set to the plane width of plane <code>i</code> in the larger image.)</dd><dd><code>height</code> - height (in pixels) of the new YUV image (or subregion)</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="YUVImage(byte[], int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>YUVImage</h4>
-<pre>public&nbsp;YUVImage(byte[]&nbsp;yuvImage,
-        int&nbsp;width,
-        int&nbsp;pad,
-        int&nbsp;height,
-        int&nbsp;subsamp)</pre>
-<div class="block">Create a new <code>YUVImage</code> instance from an existing unified image
- buffer.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>yuvImage</code> - image buffer that contains or will contain YUV planar
- image data.  Use <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>TJ.bufSizeYUV(int, int, int, int)</code></a> to determine the minimum size for
- this buffer.  The Y, U (Cb), and V (Cr) image planes are stored
- sequentially in the buffer (see <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>above</code></a> for a description
- of the image format.)</dd><dd><code>width</code> - width (in pixels) of the YUV image</dd><dd><code>pad</code> - the line padding used in the YUV image buffer.  For
- instance, if each line in each plane of the buffer is padded to the
- nearest multiple of 4 bytes, then <code>pad</code> should be set to 4.</dd><dd><code>height</code> - height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-<!-- ============ METHOD DETAIL ========== -->
-<ul class="blockList">
-<li class="blockList"><a name="method_detail">
-<!--   -->
-</a>
-<h3>Method Detail</h3>
-<a name="setBuf(byte[][], int[], int, int[], int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setBuf</h4>
-<pre>public&nbsp;void&nbsp;setBuf(byte[][]&nbsp;planes,
-          int[]&nbsp;offsets,
-          int&nbsp;width,
-          int[]&nbsp;strides,
-          int&nbsp;height,
-          int&nbsp;subsamp)</pre>
-<div class="block">Assign a set of image planes to this <code>YUVImage</code> instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>planes</code> - an array of buffers representing the Y, U (Cb), and V (Cr)
- image planes (or just the Y plane, if the image is grayscale.)  These
- planes can be contiguous or non-contiguous in memory.  Plane
- <code>i</code> should be at least <code>offsets[i] +
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#planeSizeYUV(int,%20int,%20int,%20int,%20int)"><code>TJ.planeSizeYUV</code></a>(i, width, strides[i], height, subsamp)</code>
- bytes in size.</dd><dd><code>offsets</code> - If this <code>YUVImage</code> instance represents a
- subregion of a larger image, then <code>offsets[i]</code> specifies the
- offset (in bytes) of the subregion within plane <code>i</code> of the
- larger image.  Setting this to null is the same as setting the offsets for
- all planes to 0.</dd><dd><code>width</code> - width (in pixels) of the YUV image (or subregion)</dd><dd><code>strides</code> - an array of integers, each specifying the number of bytes
- per line in the corresponding plane of the YUV image.  Setting the stride
- for any plane to 0 is the same as setting it to the plane width (see
- <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>above</code></a>.)  If <code>strides</code> is null, then the
- strides for all planes will be set to their respective plane widths.  You
- can adjust the strides in order to add an arbitrary amount of line padding
- to each plane or to specify that this <code>YUVImage</code> image is a
- subregion of a larger image (in which case, <code>strides[i]</code> should
- be set to the plane width of plane <code>i</code> in the larger image.)</dd><dd><code>height</code> - height (in pixels) of the YUV image (or subregion)</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="setBuf(byte[], int, int, int, int)">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>setBuf</h4>
-<pre>public&nbsp;void&nbsp;setBuf(byte[]&nbsp;yuvImage,
-          int&nbsp;width,
-          int&nbsp;pad,
-          int&nbsp;height,
-          int&nbsp;subsamp)</pre>
-<div class="block">Assign a unified image buffer to this <code>YUVImage</code> instance.</div>
-<dl><dt><span class="strong">Parameters:</span></dt><dd><code>yuvImage</code> - image buffer that contains or will contain YUV planar
- image data.  Use <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#bufSizeYUV(int,%20int,%20int,%20int)"><code>TJ.bufSizeYUV(int, int, int, int)</code></a> to determine the minimum size for
- this buffer.  The Y, U (Cb), and V (Cr) image planes are stored
- sequentially in the buffer (see <a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><code>above</code></a> for a description
- of the image format.)</dd><dd><code>width</code> - width (in pixels) of the YUV image</dd><dd><code>pad</code> - the line padding used in the YUV image buffer.  For
- instance, if each line in each plane of the buffer is padded to the
- nearest multiple of 4 bytes, then <code>pad</code> should be set to 4.</dd><dd><code>height</code> - height (in pixels) of the YUV image</dd><dd><code>subsamp</code> - the level of chrominance subsampling used in the YUV
- image (one of <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>)</dd></dl>
-</li>
-</ul>
-<a name="getWidth()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getWidth</h4>
-<pre>public&nbsp;int&nbsp;getWidth()</pre>
-<div class="block">Returns the width of the YUV image (or subregion.)</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the width of the YUV image (or subregion)</dd></dl>
-</li>
-</ul>
-<a name="getHeight()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getHeight</h4>
-<pre>public&nbsp;int&nbsp;getHeight()</pre>
-<div class="block">Returns the height of the YUV image (or subregion.)</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the height of the YUV image (or subregion)</dd></dl>
-</li>
-</ul>
-<a name="getPad()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getPad</h4>
-<pre>public&nbsp;int&nbsp;getPad()</pre>
-<div class="block">Returns the line padding used in the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the line padding used in the YUV image buffer</dd></dl>
-</li>
-</ul>
-<a name="getStrides()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getStrides</h4>
-<pre>public&nbsp;int[]&nbsp;getStrides()</pre>
-<div class="block">Returns the number of bytes per line of each plane in the YUV image.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the number of bytes per line of each plane in the YUV image</dd></dl>
-</li>
-</ul>
-<a name="getOffsets()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getOffsets</h4>
-<pre>public&nbsp;int[]&nbsp;getOffsets()</pre>
-<div class="block">Returns the offsets (in bytes) of each plane within the planes of a larger
- YUV image.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the offsets (in bytes) of each plane within the planes of a larger
- YUV image</dd></dl>
-</li>
-</ul>
-<a name="getSubsamp()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getSubsamp</h4>
-<pre>public&nbsp;int&nbsp;getSubsamp()</pre>
-<div class="block">Returns the level of chrominance subsampling used in the YUV image.  See
- <a href="../../../org/libjpegturbo/turbojpeg/TJ.html#SAMP_444"><code>TJ.SAMP_*</code></a>.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the level of chrominance subsampling used in the YUV image</dd></dl>
-</li>
-</ul>
-<a name="getPlanes()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getPlanes</h4>
-<pre>public&nbsp;byte[][]&nbsp;getPlanes()</pre>
-<div class="block">Returns the YUV image planes.  If the image is stored in a unified buffer,
- then all image planes will point to that buffer.</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the YUV image planes</dd></dl>
-</li>
-</ul>
-<a name="getBuf()">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>getBuf</h4>
-<pre>public&nbsp;byte[]&nbsp;getBuf()</pre>
-<div class="block">Returns the YUV image buffer (if this image is stored in a unified
- buffer rather than separate image planes.)</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the YUV image buffer</dd></dl>
-</li>
-</ul>
-<a name="getSize()">
-<!--   -->
-</a>
-<ul class="blockListLast">
-<li class="blockList">
-<h4>getSize</h4>
-<pre>public&nbsp;int&nbsp;getSize()</pre>
-<div class="block">Returns the size (in bytes) of the YUV image buffer (if this image is
- stored in a unified buffer rather than separate image planes.)</div>
-<dl><dt><span class="strong">Returns:</span></dt><dd>the size (in bytes) of the YUV image buffer</dd></dl>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-<!-- ========= END OF CLASS DATA ========= -->
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li class="navBarCell1Rev">Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">Prev Class</span></a></li>
-<li>Next Class</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/YUVImage.html" target="_top">Frames</a></li>
-<li><a href="YUVImage.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<div>
-<ul class="subNavList">
-<li>Summary:&nbsp;</li>
-<li>Nested&nbsp;|&nbsp;</li>
-<li><a href="#field_summary">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_summary">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_summary">Method</a></li>
-</ul>
-<ul class="subNavList">
-<li>Detail:&nbsp;</li>
-<li><a href="#field_detail">Field</a>&nbsp;|&nbsp;</li>
-<li><a href="#constructor_detail">Constr</a>&nbsp;|&nbsp;</li>
-<li><a href="#method_detail">Method</a></li>
-</ul>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-frame.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-frame.html
deleted file mode 100644
index 08a8bf8..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-frame.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>org.libjpegturbo.turbojpeg</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<h1 class="bar"><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html" target="classFrame">org.libjpegturbo.turbojpeg</a></h1>
-<div class="indexContainer">
-<h2 title="Interfaces">Interfaces</h2>
-<ul title="Interfaces">
-<li><a href="TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg" target="classFrame"><i>TJCustomFilter</i></a></li>
-</ul>
-<h2 title="Classes">Classes</h2>
-<ul title="Classes">
-<li><a href="TJ.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJ</a></li>
-<li><a href="TJCompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJCompressor</a></li>
-<li><a href="TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJDecompressor</a></li>
-<li><a href="TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJScalingFactor</a></li>
-<li><a href="TJTransform.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJTransform</a></li>
-<li><a href="TJTransformer.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJTransformer</a></li>
-<li><a href="YUVImage.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">YUVImage</a></li>
-</ul>
-<h2 title="Exceptions">Exceptions</h2>
-<ul title="Exceptions">
-<li><a href="TJException.html" title="class in org.libjpegturbo.turbojpeg" target="classFrame">TJException</a></li>
-</ul>
-</div>
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-summary.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-summary.html
deleted file mode 100644
index dedcce5..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-summary.html
+++ /dev/null
@@ -1,202 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>org.libjpegturbo.turbojpeg</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="org.libjpegturbo.turbojpeg";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev Package</li>
-<li>Next Package</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/package-summary.html" target="_top">Frames</a></li>
-<li><a href="package-summary.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 title="Package" class="title">Package&nbsp;org.libjpegturbo.turbojpeg</h1>
-</div>
-<div class="contentContainer">
-<ul class="blockList">
-<li class="blockList">
-<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Interface Summary table, listing interfaces, and an explanation">
-<caption><span>Interface Summary</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Interface</th>
-<th class="colLast" scope="col">Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a></td>
-<td class="colLast">
-<div class="block">Custom filter callback interface</div>
-</td>
-</tr>
-</tbody>
-</table>
-</li>
-<li class="blockList">
-<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
-<caption><span>Class Summary</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Class</th>
-<th class="colLast" scope="col">Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg">TJ</a></td>
-<td class="colLast">
-<div class="block">TurboJPEG utility class (cannot be instantiated)</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg">TJCompressor</a></td>
-<td class="colLast">
-<div class="block">TurboJPEG compressor</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg">TJDecompressor</a></td>
-<td class="colLast">
-<div class="block">TurboJPEG decompressor</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg">TJScalingFactor</a></td>
-<td class="colLast">
-<div class="block">Fractional scaling factor</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">TJTransform</a></td>
-<td class="colLast">
-<div class="block">Lossless transform parameters</div>
-</td>
-</tr>
-<tr class="rowColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg">TJTransformer</a></td>
-<td class="colLast">
-<div class="block">TurboJPEG lossless transformer</div>
-</td>
-</tr>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg">YUVImage</a></td>
-<td class="colLast">
-<div class="block">This class encapsulates a YUV planar image and the metadata
- associated with it.</div>
-</td>
-</tr>
-</tbody>
-</table>
-</li>
-<li class="blockList">
-<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Exception Summary table, listing exceptions, and an explanation">
-<caption><span>Exception Summary</span><span class="tabEnd">&nbsp;</span></caption>
-<tr>
-<th class="colFirst" scope="col">Exception</th>
-<th class="colLast" scope="col">Description</th>
-</tr>
-<tbody>
-<tr class="altColor">
-<td class="colFirst"><a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">TJException</a></td>
-<td class="colLast">&nbsp;</td>
-</tr>
-</tbody>
-</table>
-</li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="package-tree.html">Tree</a></li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev Package</li>
-<li>Next Package</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/package-summary.html" target="_top">Frames</a></li>
-<li><a href="package-summary.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-tree.html b/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-tree.html
deleted file mode 100644
index 5f0f8c3..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/org/libjpegturbo/turbojpeg/package-tree.html
+++ /dev/null
@@ -1,160 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>org.libjpegturbo.turbojpeg Class Hierarchy</title>
-<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="org.libjpegturbo.turbojpeg Class Hierarchy";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li class="navBarCell1Rev">Tree</li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/package-tree.html" target="_top">Frames</a></li>
-<li><a href="package-tree.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 class="title">Hierarchy For Package org.libjpegturbo.turbojpeg</h1>
-</div>
-<div class="contentContainer">
-<h2 title="Class Hierarchy">Class Hierarchy</h2>
-<ul>
-<li type="circle">java.lang.Object
-<ul>
-<li type="circle">java.awt.geom.RectangularShape (implements java.lang.Cloneable, java.awt.Shape)
-<ul>
-<li type="circle">java.awt.geom.Rectangle2D
-<ul>
-<li type="circle">java.awt.Rectangle (implements java.io.Serializable, java.awt.Shape)
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransform</span></a></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li type="circle">java.lang.Throwable (implements java.io.Serializable)
-<ul>
-<li type="circle">java.lang.Exception
-<ul>
-<li type="circle">java.io.IOException
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJException</span></a></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJ</span></a></li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJCompressor</span></a> (implements java.io.Closeable)</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJDecompressor</span></a> (implements java.io.Closeable)
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransformer</span></a></li>
-</ul>
-</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJScalingFactor</span></a></li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">YUVImage</span></a></li>
-</ul>
-</li>
-</ul>
-<h2 title="Interface Hierarchy">Interface Hierarchy</h2>
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="../../../org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">TJCustomFilter</span></a></li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="../../../org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li class="navBarCell1Rev">Tree</li>
-<li><a href="../../../deprecated-list.html">Deprecated</a></li>
-<li><a href="../../../index-all.html">Index</a></li>
-<li><a href="../../../help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="../../../index.html?org/libjpegturbo/turbojpeg/package-tree.html" target="_top">Frames</a></li>
-<li><a href="package-tree.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="../../../allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/overview-tree.html b/src/third_party/libjpeg-turbo/java/doc/overview-tree.html
deleted file mode 100644
index b659995..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/overview-tree.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Class Hierarchy</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="Class Hierarchy";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li class="navBarCell1Rev">Tree</li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?overview-tree.html" target="_top">Frames</a></li>
-<li><a href="overview-tree.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 class="title">Hierarchy For All Packages</h1>
-<span class="strong">Package Hierarchies:</span>
-<ul class="horizontal">
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">org.libjpegturbo.turbojpeg</a></li>
-</ul>
-</div>
-<div class="contentContainer">
-<h2 title="Class Hierarchy">Class Hierarchy</h2>
-<ul>
-<li type="circle">java.lang.Object
-<ul>
-<li type="circle">java.awt.geom.RectangularShape (implements java.lang.Cloneable, java.awt.Shape)
-<ul>
-<li type="circle">java.awt.geom.Rectangle2D
-<ul>
-<li type="circle">java.awt.Rectangle (implements java.io.Serializable, java.awt.Shape)
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransform</span></a></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li type="circle">java.lang.Throwable (implements java.io.Serializable)
-<ul>
-<li type="circle">java.lang.Exception
-<ul>
-<li type="circle">java.io.IOException
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJException</span></a></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJ.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJ</span></a></li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJCompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJCompressor</span></a> (implements java.io.Closeable)</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJDecompressor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJDecompressor</span></a> (implements java.io.Closeable)
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJTransformer.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJTransformer</span></a></li>
-</ul>
-</li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJScalingFactor.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">TJScalingFactor</span></a></li>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/YUVImage.html" title="class in org.libjpegturbo.turbojpeg"><span class="strong">YUVImage</span></a></li>
-</ul>
-</li>
-</ul>
-<h2 title="Interface Hierarchy">Interface Hierarchy</h2>
-<ul>
-<li type="circle">org.libjpegturbo.turbojpeg.<a href="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg"><span class="strong">TJCustomFilter</span></a></li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li class="navBarCell1Rev">Tree</li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?overview-tree.html" target="_top">Frames</a></li>
-<li><a href="overview-tree.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/package-list b/src/third_party/libjpeg-turbo/java/doc/package-list
deleted file mode 100644
index 918d936..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/package-list
+++ /dev/null
@@ -1 +0,0 @@
-org.libjpegturbo.turbojpeg
diff --git a/src/third_party/libjpeg-turbo/java/doc/resources/background.gif b/src/third_party/libjpeg-turbo/java/doc/resources/background.gif
deleted file mode 100644
index f471940..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/resources/background.gif
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/java/doc/resources/tab.gif b/src/third_party/libjpeg-turbo/java/doc/resources/tab.gif
deleted file mode 100644
index 1a73a83..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/resources/tab.gif
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/java/doc/resources/titlebar.gif b/src/third_party/libjpeg-turbo/java/doc/resources/titlebar.gif
deleted file mode 100644
index 17443b3..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/resources/titlebar.gif
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/java/doc/resources/titlebar_end.gif b/src/third_party/libjpeg-turbo/java/doc/resources/titlebar_end.gif
deleted file mode 100644
index 3ad78d4..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/resources/titlebar_end.gif
+++ /dev/null
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/java/doc/script.js b/src/third_party/libjpeg-turbo/java/doc/script.js
deleted file mode 100644
index b346356..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/script.js
+++ /dev/null
@@ -1,30 +0,0 @@
-function show(type)
-{
-    count = 0;
-    for (var key in methods) {
-        var row = document.getElementById(key);
-        if ((methods[key] &  type) != 0) {
-            row.style.display = '';
-            row.className = (count++ % 2) ? rowColor : altColor;
-        }
-        else
-            row.style.display = 'none';
-    }
-    updateTabs(type);
-}
-
-function updateTabs(type)
-{
-    for (var value in tabs) {
-        var sNode = document.getElementById(tabs[value][0]);
-        var spanNode = sNode.firstChild;
-        if (value == type) {
-            sNode.className = activeTableTab;
-            spanNode.innerHTML = tabs[value][1];
-        }
-        else {
-            sNode.className = tableTab;
-            spanNode.innerHTML = "<a href=\"javascript:show("+ value + ");\">" + tabs[value][1] + "</a>";
-        }
-    }
-}
diff --git a/src/third_party/libjpeg-turbo/java/doc/serialized-form.html b/src/third_party/libjpeg-turbo/java/doc/serialized-form.html
deleted file mode 100644
index 45bbc86..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/serialized-form.html
+++ /dev/null
@@ -1,176 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<!-- NewPage -->
-<html lang="en">
-<head>
-<title>Serialized Form</title>
-<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
-</head>
-<body>
-<script type="text/javascript"><!--
-    try {
-        if (location.href.indexOf('is-external=true') == -1) {
-            parent.document.title="Serialized Form";
-        }
-    }
-    catch(err) {
-    }
-//-->
-</script>
-<noscript>
-<div>JavaScript is disabled on your browser.</div>
-</noscript>
-<!-- ========= START OF TOP NAVBAR ======= -->
-<div class="topNav"><a name="navbar_top">
-<!--   -->
-</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?serialized-form.html" target="_top">Frames</a></li>
-<li><a href="serialized-form.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_top">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_top");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_top">
-<!--   -->
-</a></div>
-<!-- ========= END OF TOP NAVBAR ========= -->
-<div class="header">
-<h1 title="Serialized Form" class="title">Serialized Form</h1>
-</div>
-<div class="serializedFormContainer">
-<ul class="blockList">
-<li class="blockList">
-<h2 title="Package">Package&nbsp;org.libjpegturbo.turbojpeg</h2>
-<ul class="blockList">
-<li class="blockList"><a name="org.libjpegturbo.turbojpeg.TJException">
-<!--   -->
-</a>
-<h3>Class <a href="org/libjpegturbo/turbojpeg/TJException.html" title="class in org.libjpegturbo.turbojpeg">org.libjpegturbo.turbojpeg.TJException</a> extends java.io.IOException implements Serializable</h3>
-<dl class="nameValue">
-<dt>serialVersionUID:</dt>
-<dd>1L</dd>
-</dl>
-<ul class="blockList">
-<li class="blockList"><a name="serializedForm">
-<!--   -->
-</a>
-<h3>Serialized Fields</h3>
-<ul class="blockList">
-<li class="blockListLast">
-<h4>errorCode</h4>
-<pre>int errorCode</pre>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-<li class="blockList"><a name="org.libjpegturbo.turbojpeg.TJTransform">
-<!--   -->
-</a>
-<h3>Class <a href="org/libjpegturbo/turbojpeg/TJTransform.html" title="class in org.libjpegturbo.turbojpeg">org.libjpegturbo.turbojpeg.TJTransform</a> extends java.awt.Rectangle implements Serializable</h3>
-<dl class="nameValue">
-<dt>serialVersionUID:</dt>
-<dd>-127367705761430371L</dd>
-</dl>
-<ul class="blockList">
-<li class="blockList"><a name="serializedForm">
-<!--   -->
-</a>
-<h3>Serialized Fields</h3>
-<ul class="blockList">
-<li class="blockList">
-<h4>op</h4>
-<pre>int op</pre>
-<div class="block">Transform operation (one of <code>OP_*</code>)</div>
-</li>
-<li class="blockList">
-<h4>options</h4>
-<pre>int options</pre>
-<div class="block">Transform options (bitwise OR of one or more of <code>OPT_*</code>)</div>
-</li>
-<li class="blockListLast">
-<h4>cf</h4>
-<pre><a href="org/libjpegturbo/turbojpeg/TJCustomFilter.html" title="interface in org.libjpegturbo.turbojpeg">TJCustomFilter</a> cf</pre>
-<div class="block">Custom filter instance</div>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->
-<div class="bottomNav"><a name="navbar_bottom">
-<!--   -->
-</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
-<!--   -->
-</a>
-<ul class="navList" title="Navigation">
-<li><a href="org/libjpegturbo/turbojpeg/package-summary.html">Package</a></li>
-<li>Class</li>
-<li><a href="org/libjpegturbo/turbojpeg/package-tree.html">Tree</a></li>
-<li><a href="deprecated-list.html">Deprecated</a></li>
-<li><a href="index-all.html">Index</a></li>
-<li><a href="help-doc.html">Help</a></li>
-</ul>
-</div>
-<div class="subNav">
-<ul class="navList">
-<li>Prev</li>
-<li>Next</li>
-</ul>
-<ul class="navList">
-<li><a href="index.html?serialized-form.html" target="_top">Frames</a></li>
-<li><a href="serialized-form.html" target="_top">No Frames</a></li>
-</ul>
-<ul class="navList" id="allclasses_navbar_bottom">
-<li><a href="allclasses-noframe.html">All Classes</a></li>
-</ul>
-<div>
-<script type="text/javascript"><!--
-  allClassesLink = document.getElementById("allclasses_navbar_bottom");
-  if(window==top) {
-    allClassesLink.style.display = "block";
-  }
-  else {
-    allClassesLink.style.display = "none";
-  }
-  //-->
-</script>
-</div>
-<a name="skip-navbar_bottom">
-<!--   -->
-</a></div>
-<!-- ======== END OF BOTTOM NAVBAR ======= -->
-</body>
-</html>
diff --git a/src/third_party/libjpeg-turbo/java/doc/stylesheet.css b/src/third_party/libjpeg-turbo/java/doc/stylesheet.css
deleted file mode 100644
index 0aeaa97..0000000
--- a/src/third_party/libjpeg-turbo/java/doc/stylesheet.css
+++ /dev/null
@@ -1,474 +0,0 @@
-/* Javadoc style sheet */
-/*
-Overall document style
-*/
-body {
-    background-color:#ffffff;
-    color:#353833;
-    font-family:Arial, Helvetica, sans-serif;
-    font-size:76%;
-    margin:0;
-}
-a:link, a:visited {
-    text-decoration:none;
-    color:#4c6b87;
-}
-a:hover, a:focus {
-    text-decoration:none;
-    color:#bb7a2a;
-}
-a:active {
-    text-decoration:none;
-    color:#4c6b87;
-}
-a[name] {
-    color:#353833;
-}
-a[name]:hover {
-    text-decoration:none;
-    color:#353833;
-}
-pre {
-    font-size:1.3em;
-}
-h1 {
-    font-size:1.8em;
-}
-h2 {
-    font-size:1.5em;
-}
-h3 {
-    font-size:1.4em;
-}
-h4 {
-    font-size:1.3em;
-}
-h5 {
-    font-size:1.2em;
-}
-h6 {
-    font-size:1.1em;
-}
-ul {
-    list-style-type:disc;
-}
-code, tt {
-    font-size:1.2em;
-}
-dt code {
-    font-size:1.2em;
-}
-table tr td dt code {
-    font-size:1.2em;
-    vertical-align:top;
-}
-sup {
-    font-size:.6em;
-}
-/*
-Document title and Copyright styles
-*/
-.clear {
-    clear:both;
-    height:0px;
-    overflow:hidden;
-}
-.aboutLanguage {
-    float:right;
-    padding:0px 21px;
-    font-size:.8em;
-    z-index:200;
-    margin-top:-7px;
-}
-.legalCopy {
-    margin-left:.5em;
-}
-.bar a, .bar a:link, .bar a:visited, .bar a:active {
-    color:#FFFFFF;
-    text-decoration:none;
-}
-.bar a:hover, .bar a:focus {
-    color:#bb7a2a;
-}
-.tab {
-    background-color:#0066FF;
-    background-image:url(resources/titlebar.gif);
-    background-position:left top;
-    background-repeat:no-repeat;
-    color:#ffffff;
-    padding:8px;
-    width:5em;
-    font-weight:bold;
-}
-/*
-Navigation bar styles
-*/
-.bar {
-    background-image:url(resources/background.gif);
-    background-repeat:repeat-x;
-    color:#FFFFFF;
-    padding:.8em .5em .4em .8em;
-    height:auto;/*height:1.8em;*/
-    font-size:1em;
-    margin:0;
-}
-.topNav {
-    background-image:url(resources/background.gif);
-    background-repeat:repeat-x;
-    color:#FFFFFF;
-    float:left;
-    padding:0;
-    width:100%;
-    clear:right;
-    height:2.8em;
-    padding-top:10px;
-    overflow:hidden;
-}
-.bottomNav {
-    margin-top:10px;
-    background-image:url(resources/background.gif);
-    background-repeat:repeat-x;
-    color:#FFFFFF;
-    float:left;
-    padding:0;
-    width:100%;
-    clear:right;
-    height:2.8em;
-    padding-top:10px;
-    overflow:hidden;
-}
-.subNav {
-    background-color:#dee3e9;
-    border-bottom:1px solid #9eadc0;
-    float:left;
-    width:100%;
-    overflow:hidden;
-}
-.subNav div {
-    clear:left;
-    float:left;
-    padding:0 0 5px 6px;
-}
-ul.navList, ul.subNavList {
-    float:left;
-    margin:0 25px 0 0;
-    padding:0;
-}
-ul.navList li{
-    list-style:none;
-    float:left;
-    padding:3px 6px;
-}
-ul.subNavList li{
-    list-style:none;
-    float:left;
-    font-size:90%;
-}
-.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
-    color:#FFFFFF;
-    text-decoration:none;
-}
-.topNav a:hover, .bottomNav a:hover {
-    text-decoration:none;
-    color:#bb7a2a;
-}
-.navBarCell1Rev {
-    background-image:url(resources/tab.gif);
-    background-color:#a88834;
-    color:#FFFFFF;
-    margin: auto 5px;
-    border:1px solid #c9aa44;
-}
-/*
-Page header and footer styles
-*/
-.header, .footer {
-    clear:both;
-    margin:0 20px;
-    padding:5px 0 0 0;
-}
-.indexHeader {
-    margin:10px;
-    position:relative;
-}
-.indexHeader h1 {
-    font-size:1.3em;
-}
-.title {
-    color:#2c4557;
-    margin:10px 0;
-}
-.subTitle {
-    margin:5px 0 0 0;
-}
-.header ul {
-    margin:0 0 25px 0;
-    padding:0;
-}
-.footer ul {
-    margin:20px 0 5px 0;
-}
-.header ul li, .footer ul li {
-    list-style:none;
-    font-size:1.2em;
-}
-/*
-Heading styles
-*/
-div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
-    background-color:#dee3e9;
-    border-top:1px solid #9eadc0;
-    border-bottom:1px solid #9eadc0;
-    margin:0 0 6px -8px;
-    padding:2px 5px;
-}
-ul.blockList ul.blockList ul.blockList li.blockList h3 {
-    background-color:#dee3e9;
-    border-top:1px solid #9eadc0;
-    border-bottom:1px solid #9eadc0;
-    margin:0 0 6px -8px;
-    padding:2px 5px;
-}
-ul.blockList ul.blockList li.blockList h3 {
-    padding:0;
-    margin:15px 0;
-}
-ul.blockList li.blockList h2 {
-    padding:0px 0 20px 0;
-}
-/*
-Page layout container styles
-*/
-.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
-    clear:both;
-    padding:10px 20px;
-    position:relative;
-}
-.indexContainer {
-    margin:10px;
-    position:relative;
-    font-size:1.0em;
-}
-.indexContainer h2 {
-    font-size:1.1em;
-    padding:0 0 3px 0;
-}
-.indexContainer ul {
-    margin:0;
-    padding:0;
-}
-.indexContainer ul li {
-    list-style:none;
-}
-.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
-    font-size:1.1em;
-    font-weight:bold;
-    margin:10px 0 0 0;
-    color:#4E4E4E;
-}
-.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
-    margin:10px 0 10px 20px;
-}
-.serializedFormContainer dl.nameValue dt {
-    margin-left:1px;
-    font-size:1.1em;
-    display:inline;
-    font-weight:bold;
-}
-.serializedFormContainer dl.nameValue dd {
-    margin:0 0 0 1px;
-    font-size:1.1em;
-    display:inline;
-}
-/*
-List styles
-*/
-ul.horizontal li {
-    display:inline;
-    font-size:0.9em;
-}
-ul.inheritance {
-    margin:0;
-    padding:0;
-}
-ul.inheritance li {
-    display:inline;
-    list-style:none;
-}
-ul.inheritance li ul.inheritance {
-    margin-left:15px;
-    padding-left:15px;
-    padding-top:1px;
-}
-ul.blockList, ul.blockListLast {
-    margin:10px 0 10px 0;
-    padding:0;
-}
-ul.blockList li.blockList, ul.blockListLast li.blockList {
-    list-style:none;
-    margin-bottom:25px;
-}
-ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
-    padding:0px 20px 5px 10px;
-    border:1px solid #9eadc0;
-    background-color:#f9f9f9;
-}
-ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
-    padding:0 0 5px 8px;
-    background-color:#ffffff;
-    border:1px solid #9eadc0;
-    border-top:none;
-}
-ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
-    margin-left:0;
-    padding-left:0;
-    padding-bottom:15px;
-    border:none;
-    border-bottom:1px solid #9eadc0;
-}
-ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
-    list-style:none;
-    border-bottom:none;
-    padding-bottom:0;
-}
-table tr td dl, table tr td dl dt, table tr td dl dd {
-    margin-top:0;
-    margin-bottom:1px;
-}
-/*
-Table styles
-*/
-.contentContainer table, .classUseContainer table, .constantValuesContainer table {
-    border-bottom:1px solid #9eadc0;
-    width:100%;
-}
-.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
-    width:100%;
-}
-.contentContainer .description table, .contentContainer .details table {
-    border-bottom:none;
-}
-.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
-    vertical-align:top;
-    padding-right:20px;
-}
-.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
-.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
-.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
-.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
-    padding-right:3px;
-}
-.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
-    position:relative;
-    text-align:left;
-    background-repeat:no-repeat;
-    color:#FFFFFF;
-    font-weight:bold;
-    clear:none;
-    overflow:hidden;
-    padding:0px;
-    margin:0px;
-}
-caption a:link, caption a:hover, caption a:active, caption a:visited {
-    color:#FFFFFF;
-}
-.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
-    white-space:nowrap;
-    padding-top:8px;
-    padding-left:8px;
-    display:block;
-    float:left;
-    background-image:url(resources/titlebar.gif);
-    height:18px;
-}
-.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
-    width:10px;
-    background-image:url(resources/titlebar_end.gif);
-    background-repeat:no-repeat;
-    background-position:top right;
-    position:relative;
-    float:left;
-}
-ul.blockList ul.blockList li.blockList table {
-    margin:0 0 12px 0px;
-    width:100%;
-}
-.tableSubHeadingColor {
-    background-color: #EEEEFF;
-}
-.altColor {
-    background-color:#eeeeef;
-}
-.rowColor {
-    background-color:#ffffff;
-}
-.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
-    text-align:left;
-    padding:3px 3px 3px 7px;
-}
-th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
-    background:#dee3e9;
-    border-top:1px solid #9eadc0;
-    border-bottom:1px solid #9eadc0;
-    text-align:left;
-    padding:3px 3px 3px 7px;
-}
-td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
-    font-weight:bold;
-}
-td.colFirst, th.colFirst {
-    border-left:1px solid #9eadc0;
-    white-space:nowrap;
-}
-td.colLast, th.colLast {
-    border-right:1px solid #9eadc0;
-}
-td.colOne, th.colOne {
-    border-right:1px solid #9eadc0;
-    border-left:1px solid #9eadc0;
-}
-table.overviewSummary  {
-    padding:0px;
-    margin-left:0px;
-}
-table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
-table.overviewSummary td.colOne, table.overviewSummary th.colOne {
-    width:25%;
-    vertical-align:middle;
-}
-table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
-    width:25%;
-    vertical-align:middle;
-}
-/*
-Content styles
-*/
-.description pre {
-    margin-top:0;
-}
-.deprecatedContent {
-    margin:0;
-    padding:10px 0;
-}
-.docSummary {
-    padding:0;
-}
-/*
-Formatting effect styles
-*/
-.sourceLineNo {
-    color:green;
-    padding:0 30px 0 0;
-}
-h1.hidden {
-    visibility:hidden;
-    overflow:hidden;
-    font-size:.9em;
-}
-.block {
-    display:block;
-    margin:3px 0 0 0;
-}
-.strong {
-    font-weight:bold;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java
deleted file mode 100644
index fbb49df..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright (C)2011-2013, 2017-2018 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-/**
- * TurboJPEG utility class (cannot be instantiated)
- */
-public final class TJ {
-
-  private TJ() {}
-
-  /**
-   * The number of chrominance subsampling options
-   */
-  public static final int NUMSAMP   = 6;
-  /**
-   * 4:4:4 chrominance subsampling (no chrominance subsampling).  The JPEG
-   * or YUV image will contain one chrominance component for every pixel in the
-   * source image.
-   */
-  public static final int SAMP_444  = 0;
-  /**
-   * 4:2:2 chrominance subsampling.  The JPEG or YUV image will contain one
-   * chrominance component for every 2x1 block of pixels in the source image.
-   */
-  public static final int SAMP_422  = 1;
-  /**
-   * 4:2:0 chrominance subsampling.  The JPEG or YUV image will contain one
-   * chrominance component for every 2x2 block of pixels in the source image.
-   */
-  public static final int SAMP_420  = 2;
-  /**
-   * Grayscale.  The JPEG or YUV image will contain no chrominance components.
-   */
-  public static final int SAMP_GRAY = 3;
-  /**
-   * 4:4:0 chrominance subsampling.  The JPEG or YUV image will contain one
-   * chrominance component for every 1x2 block of pixels in the source image.
-   * Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
-   */
-  public static final int SAMP_440  = 4;
-  /**
-   * 4:1:1 chrominance subsampling.  The JPEG or YUV image will contain one
-   * chrominance component for every 4x1 block of pixels in the source image.
-   * JPEG images compressed with 4:1:1 subsampling will be almost exactly the
-   * same size as those compressed with 4:2:0 subsampling, and in the
-   * aggregate, both subsampling methods produce approximately the same
-   * perceptual quality.  However, 4:1:1 is better able to reproduce sharp
-   * horizontal features.  Note that 4:1:1 subsampling is not fully accelerated
-   * in libjpeg-turbo.
-   */
-  public static final int SAMP_411  = 5;
-
-
-  /**
-   * Returns the MCU block width for the given level of chrominance
-   * subsampling.
-   *
-   * @param subsamp the level of chrominance subsampling (one of
-   * <code>SAMP_*</code>)
-   *
-   * @return the MCU block width for the given level of chrominance
-   * subsampling.
-   */
-  public static int getMCUWidth(int subsamp) {
-    checkSubsampling(subsamp);
-    return MCU_WIDTH[subsamp];
-  }
-
-  private static final int[] MCU_WIDTH = {
-    8, 16, 16, 8, 8, 32
-  };
-
-
-  /**
-   * Returns the MCU block height for the given level of chrominance
-   * subsampling.
-   *
-   * @param subsamp the level of chrominance subsampling (one of
-   * <code>SAMP_*</code>)
-   *
-   * @return the MCU block height for the given level of chrominance
-   * subsampling.
-   */
-  public static int getMCUHeight(int subsamp) {
-    checkSubsampling(subsamp);
-    return MCU_HEIGHT[subsamp];
-  }
-
-  private static final int[] MCU_HEIGHT = {
-    8, 8, 16, 8, 16, 8
-  };
-
-
-  /**
-   * The number of pixel formats
-   */
-  public static final int NUMPF   = 12;
-  /**
-   * RGB pixel format.  The red, green, and blue components in the image are
-   * stored in 3-byte pixels in the order R, G, B from lowest to highest byte
-   * address within each pixel.
-   */
-  public static final int PF_RGB  = 0;
-  /**
-   * BGR pixel format.  The red, green, and blue components in the image are
-   * stored in 3-byte pixels in the order B, G, R from lowest to highest byte
-   * address within each pixel.
-   */
-  public static final int PF_BGR  = 1;
-  /**
-   * RGBX pixel format.  The red, green, and blue components in the image are
-   * stored in 4-byte pixels in the order R, G, B from lowest to highest byte
-   * address within each pixel.  The X component is ignored when compressing
-   * and undefined when decompressing.
-   */
-  public static final int PF_RGBX = 2;
-  /**
-   * BGRX pixel format.  The red, green, and blue components in the image are
-   * stored in 4-byte pixels in the order B, G, R from lowest to highest byte
-   * address within each pixel.  The X component is ignored when compressing
-   * and undefined when decompressing.
-   */
-  public static final int PF_BGRX = 3;
-  /**
-   * XBGR pixel format.  The red, green, and blue components in the image are
-   * stored in 4-byte pixels in the order R, G, B from highest to lowest byte
-   * address within each pixel.  The X component is ignored when compressing
-   * and undefined when decompressing.
-   */
-  public static final int PF_XBGR = 4;
-  /**
-   * XRGB pixel format.  The red, green, and blue components in the image are
-   * stored in 4-byte pixels in the order B, G, R from highest to lowest byte
-   * address within each pixel.  The X component is ignored when compressing
-   * and undefined when decompressing.
-   */
-  public static final int PF_XRGB = 5;
-  /**
-   * Grayscale pixel format.  Each 1-byte pixel represents a luminance
-   * (brightness) level from 0 to 255.
-   */
-  public static final int PF_GRAY = 6;
-  /**
-   * RGBA pixel format.  This is the same as {@link #PF_RGBX}, except that when
-   * decompressing, the X byte is guaranteed to be 0xFF, which can be
-   * interpreted as an opaque alpha channel.
-   */
-  public static final int PF_RGBA = 7;
-  /**
-   * BGRA pixel format.  This is the same as {@link #PF_BGRX}, except that when
-   * decompressing, the X byte is guaranteed to be 0xFF, which can be
-   * interpreted as an opaque alpha channel.
-   */
-  public static final int PF_BGRA = 8;
-  /**
-   * ABGR pixel format.  This is the same as {@link #PF_XBGR}, except that when
-   * decompressing, the X byte is guaranteed to be 0xFF, which can be
-   * interpreted as an opaque alpha channel.
-   */
-  public static final int PF_ABGR = 9;
-  /**
-   * ARGB pixel format.  This is the same as {@link #PF_XRGB}, except that when
-   * decompressing, the X byte is guaranteed to be 0xFF, which can be
-   * interpreted as an opaque alpha channel.
-   */
-  public static final int PF_ARGB = 10;
-  /**
-   * CMYK pixel format.  Unlike RGB, which is an additive color model used
-   * primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive
-   * color model used primarily for printing.  In the CMYK color model, the
-   * value of each color component typically corresponds to an amount of cyan,
-   * magenta, yellow, or black ink that is applied to a white background.  In
-   * order to convert between CMYK and RGB, it is necessary to use a color
-   * management system (CMS.)  A CMS will attempt to map colors within the
-   * printer's gamut to perceptually similar colors in the display's gamut and
-   * vice versa, but the mapping is typically not 1:1 or reversible, nor can it
-   * be defined with a simple formula.  Thus, such a conversion is out of scope
-   * for a codec library.  However, the TurboJPEG API allows for compressing
-   * CMYK pixels into a YCCK JPEG image (see {@link #CS_YCCK}) and
-   * decompressing YCCK JPEG images into CMYK pixels.
-   */
-  public static final int PF_CMYK = 11;
-
-
-  /**
-   * Returns the pixel size (in bytes) for the given pixel format.
-   *
-   * @param pixelFormat the pixel format (one of <code>PF_*</code>)
-   *
-   * @return the pixel size (in bytes) for the given pixel format.
-   */
-  public static int getPixelSize(int pixelFormat) {
-    checkPixelFormat(pixelFormat);
-    return PIXEL_SIZE[pixelFormat];
-  }
-
-  private static final int[] PIXEL_SIZE = {
-    3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4, 4
-  };
-
-
-  /**
-   * For the given pixel format, returns the number of bytes that the red
-   * component is offset from the start of the pixel.  For instance, if a pixel
-   * of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
-   * then the red component will be
-   * <code>pixel[TJ.getRedOffset(TJ.PF_BGRX)]</code>.
-   *
-   * @param pixelFormat the pixel format (one of <code>PF_*</code>)
-   *
-   * @return the red offset for the given pixel format, or -1 if the pixel
-   * format does not have a red component.
-   */
-  public static int getRedOffset(int pixelFormat) {
-    checkPixelFormat(pixelFormat);
-    return RED_OFFSET[pixelFormat];
-  }
-
-  private static final int[] RED_OFFSET = {
-    0, 2, 0, 2, 3, 1, -1, 0, 2, 3, 1, -1
-  };
-
-
-  /**
-   * For the given pixel format, returns the number of bytes that the green
-   * component is offset from the start of the pixel.  For instance, if a pixel
-   * of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
-   * then the green component will be
-   * <code>pixel[TJ.getGreenOffset(TJ.PF_BGRX)]</code>.
-   *
-   * @param pixelFormat the pixel format (one of <code>PF_*</code>)
-   *
-   * @return the green offset for the given pixel format, or -1 if the pixel
-   * format does not have a green component.
-   */
-  public static int getGreenOffset(int pixelFormat) {
-    checkPixelFormat(pixelFormat);
-    return GREEN_OFFSET[pixelFormat];
-  }
-
-  private static final int[] GREEN_OFFSET = {
-    1, 1, 1, 1, 2, 2, -1, 1, 1, 2, 2, -1
-  };
-
-
-  /**
-   * For the given pixel format, returns the number of bytes that the blue
-   * component is offset from the start of the pixel.  For instance, if a pixel
-   * of format <code>TJ.PF_BGRX</code> is stored in <code>char pixel[]</code>,
-   * then the blue component will be
-   * <code>pixel[TJ.getBlueOffset(TJ.PF_BGRX)]</code>.
-   *
-   * @param pixelFormat the pixel format (one of <code>PF_*</code>)
-   *
-   * @return the blue offset for the given pixel format, or -1 if the pixel
-   * format does not have a blue component.
-   */
-  public static int getBlueOffset(int pixelFormat) {
-    checkPixelFormat(pixelFormat);
-    return BLUE_OFFSET[pixelFormat];
-  }
-
-  private static final int[] BLUE_OFFSET = {
-    2, 0, 2, 0, 1, 3, -1, 2, 0, 1, 3, -1
-  };
-
-
-  /**
-   * For the given pixel format, returns the number of bytes that the alpha
-   * component is offset from the start of the pixel.  For instance, if a pixel
-   * of format <code>TJ.PF_BGRA</code> is stored in <code>char pixel[]</code>,
-   * then the alpha component will be
-   * <code>pixel[TJ.getAlphaOffset(TJ.PF_BGRA)]</code>.
-   *
-   * @param pixelFormat the pixel format (one of <code>PF_*</code>)
-   *
-   * @return the alpha offset for the given pixel format, or -1 if the pixel
-   * format does not have a alpha component.
-   */
-  public static int getAlphaOffset(int pixelFormat) {
-    checkPixelFormat(pixelFormat);
-    return ALPHA_OFFSET[pixelFormat];
-  }
-
-  private static final int[] ALPHA_OFFSET = {
-    -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
-  };
-
-
-  /**
-   * The number of JPEG colorspaces
-   */
-  public static final int NUMCS = 5;
-  /**
-   * RGB colorspace.  When compressing the JPEG image, the R, G, and B
-   * components in the source image are reordered into image planes, but no
-   * colorspace conversion or subsampling is performed.  RGB JPEG images can be
-   * decompressed to any of the extended RGB pixel formats or grayscale, but
-   * they cannot be decompressed to YUV images.
-   */
-  public static final int CS_RGB = 0;
-  /**
-   * YCbCr colorspace.  YCbCr is not an absolute colorspace but rather a
-   * mathematical transformation of RGB designed solely for storage and
-   * transmission.  YCbCr images must be converted to RGB before they can
-   * actually be displayed.  In the YCbCr colorspace, the Y (luminance)
-   * component represents the black & white portion of the original image, and
-   * the Cb and Cr (chrominance) components represent the color portion of the
-   * original image.  Originally, the analog equivalent of this transformation
-   * allowed the same signal to drive both black & white and color televisions,
-   * but JPEG images use YCbCr primarily because it allows the color data to be
-   * optionally subsampled for the purposes of reducing bandwidth or disk
-   * space.  YCbCr is the most common JPEG colorspace, and YCbCr JPEG images
-   * can be compressed from and decompressed to any of the extended RGB pixel
-   * formats or grayscale, or they can be decompressed to YUV planar images.
-   */
-  @SuppressWarnings("checkstyle:ConstantName")
-  public static final int CS_YCbCr = 1;
-  /**
-   * Grayscale colorspace.  The JPEG image retains only the luminance data (Y
-   * component), and any color data from the source image is discarded.
-   * Grayscale JPEG images can be compressed from and decompressed to any of
-   * the extended RGB pixel formats or grayscale, or they can be decompressed
-   * to YUV planar images.
-   */
-  public static final int CS_GRAY = 2;
-  /**
-   * CMYK colorspace.  When compressing the JPEG image, the C, M, Y, and K
-   * components in the source image are reordered into image planes, but no
-   * colorspace conversion or subsampling is performed.  CMYK JPEG images can
-   * only be decompressed to CMYK pixels.
-   */
-  public static final int CS_CMYK = 3;
-  /**
-   * YCCK colorspace.  YCCK (AKA "YCbCrK") is not an absolute colorspace but
-   * rather a mathematical transformation of CMYK designed solely for storage
-   * and transmission.  It is to CMYK as YCbCr is to RGB.  CMYK pixels can be
-   * reversibly transformed into YCCK, and as with YCbCr, the chrominance
-   * components in the YCCK pixels can be subsampled without incurring major
-   * perceptual loss.  YCCK JPEG images can only be compressed from and
-   * decompressed to CMYK pixels.
-   */
-  public static final int CS_YCCK = 4;
-
-
-  /**
-   * The uncompressed source/destination image is stored in bottom-up (Windows,
-   * OpenGL) order, not top-down (X11) order.
-   */
-  public static final int FLAG_BOTTOMUP      = 2;
-
-  @SuppressWarnings("checkstyle:JavadocVariable")
-  @Deprecated
-  public static final int FLAG_FORCEMMX      = 8;
-  @SuppressWarnings("checkstyle:JavadocVariable")
-  @Deprecated
-  public static final int FLAG_FORCESSE      = 16;
-  @SuppressWarnings("checkstyle:JavadocVariable")
-  @Deprecated
-  public static final int FLAG_FORCESSE2     = 32;
-  @SuppressWarnings("checkstyle:JavadocVariable")
-  @Deprecated
-  public static final int FLAG_FORCESSE3     = 128;
-
-  /**
-   * When decompressing an image that was compressed using chrominance
-   * subsampling, use the fastest chrominance upsampling algorithm available in
-   * the underlying codec.  The default is to use smooth upsampling, which
-   * creates a smooth transition between neighboring chrominance components in
-   * order to reduce upsampling artifacts in the decompressed image.
-   */
-  public static final int FLAG_FASTUPSAMPLE  = 256;
-  /**
-   * Use the fastest DCT/IDCT algorithm available in the underlying codec.  The
-   * default if this flag is not specified is implementation-specific.  For
-   * example, the implementation of TurboJPEG for libjpeg[-turbo] uses the fast
-   * algorithm by default when compressing, because this has been shown to have
-   * only a very slight effect on accuracy, but it uses the accurate algorithm
-   * when decompressing, because this has been shown to have a larger effect.
-   */
-  public static final int FLAG_FASTDCT       = 2048;
-  /**
-   * Use the most accurate DCT/IDCT algorithm available in the underlying
-   * codec.  The default if this flag is not specified is
-   * implementation-specific.  For example, the implementation of TurboJPEG for
-   * libjpeg[-turbo] uses the fast algorithm by default when compressing,
-   * because this has been shown to have only a very slight effect on accuracy,
-   * but it uses the accurate algorithm when decompressing, because this has
-   * been shown to have a larger effect.
-   */
-  public static final int FLAG_ACCURATEDCT   = 4096;
-  /**
-   * Immediately discontinue the current compression/decompression/transform
-   * operation if the underlying codec throws a warning (non-fatal error).  The
-   * default behavior is to allow the operation to complete unless a fatal
-   * error is encountered.
-   * <p>
-   * NOTE: due to the design of the TurboJPEG Java API, only certain methods
-   * (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods
-   * with a void return type) will complete and leave the output image in a
-   * fully recoverable state after a non-fatal error occurs.
-   */
-  public static final int FLAG_STOPONWARNING = 8192;
-  /**
-   * Use progressive entropy coding in JPEG images generated by compression and
-   * transform operations.  Progressive entropy coding will generally improve
-   * compression relative to baseline entropy coding (the default), but it will
-   * reduce compression and decompression performance considerably.
-   */
-  public static final int FLAG_PROGRESSIVE   = 16384;
-
-
-  /**
-   * The number of error codes
-   */
-  public static final int NUMERR = 2;
-  /**
-   * The error was non-fatal and recoverable, but the image may still be
-   * corrupt.
-   * <p>
-   * NOTE: due to the design of the TurboJPEG Java API, only certain methods
-   * (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods
-   * with a void return type) will complete and leave the output image in a
-   * fully recoverable state after a non-fatal error occurs.
-   */
-  public static final int ERR_WARNING = 0;
-  /**
-   * The error was fatal and non-recoverable.
-   */
-  public static final int ERR_FATAL = 1;
-
-
-  /**
-   * Returns the maximum size of the buffer (in bytes) required to hold a JPEG
-   * image with the given width, height, and level of chrominance subsampling.
-   *
-   * @param width the width (in pixels) of the JPEG image
-   *
-   * @param height the height (in pixels) of the JPEG image
-   *
-   * @param jpegSubsamp the level of chrominance subsampling to be used when
-   * generating the JPEG image (one of {@link TJ TJ.SAMP_*})
-   *
-   * @return the maximum size of the buffer (in bytes) required to hold a JPEG
-   * image with the given width, height, and level of chrominance subsampling.
-   */
-  public static native int bufSize(int width, int height, int jpegSubsamp);
-
-  /**
-   * Returns the size of the buffer (in bytes) required to hold a YUV planar
-   * image with the given width, height, and level of chrominance subsampling.
-   *
-   * @param width the width (in pixels) of the YUV image
-   *
-   * @param pad the width of each line in each plane of the image is padded to
-   * the nearest multiple of this number of bytes (must be a power of 2.)
-   *
-   * @param height the height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ TJ.SAMP_*})
-   *
-   * @return the size of the buffer (in bytes) required to hold a YUV planar
-   * image with the given width, height, and level of chrominance subsampling.
-   */
-  public static native int bufSizeYUV(int width, int pad, int height,
-                                      int subsamp);
-
-  /**
-   * @deprecated Use {@link #bufSizeYUV(int, int, int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public static native int bufSizeYUV(int width, int height, int subsamp);
-
-  /**
-   * Returns the size of the buffer (in bytes) required to hold a YUV image
-   * plane with the given parameters.
-   *
-   * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
-   * 2 = V/Cr)
-   *
-   * @param width width (in pixels) of the YUV image.  NOTE: this is the width
-   * of the whole image, not the plane width.
-   *
-   * @param stride bytes per line in the image plane.
-   *
-   * @param height height (in pixels) of the YUV image.  NOTE: this is the
-   * height of the whole image, not the plane height.
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ TJ.SAMP_*})
-   *
-   * @return the size of the buffer (in bytes) required to hold a YUV planar
-   * image with the given parameters.
-   */
-  public static native int planeSizeYUV(int componentID, int width, int stride,
-                                        int height, int subsamp);
-
-  /**
-   * Returns the plane width of a YUV image plane with the given parameters.
-   * Refer to {@link YUVImage YUVImage} for a description of plane width.
-   *
-   * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
-   * 2 = V/Cr)
-   *
-   * @param width width (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV image
-   * (one of {@link TJ TJ.SAMP_*})
-   *
-   * @return the plane width of a YUV image plane with the given parameters.
-   */
-  public static native int planeWidth(int componentID, int width, int subsamp);
-
-  /**
-   * Returns the plane height of a YUV image plane with the given parameters.
-   * Refer to {@link YUVImage YUVImage} for a description of plane height.
-   *
-   * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb,
-   * 2 = V/Cr)
-   *
-   * @param height height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV image
-   * (one of {@link TJ TJ.SAMP_*})
-   *
-   * @return the plane height of a YUV image plane with the given parameters.
-   */
-  public static native int planeHeight(int componentID, int height,
-                                       int subsamp);
-
-  /**
-   * Returns a list of fractional scaling factors that the JPEG decompressor in
-   * this implementation of TurboJPEG supports.
-   *
-   * @return a list of fractional scaling factors that the JPEG decompressor in
-   * this implementation of TurboJPEG supports.
-   */
-  public static native TJScalingFactor[] getScalingFactors();
-
-  static {
-    TJLoader.load();
-  }
-
-  private static void checkPixelFormat(int pixelFormat) {
-    if (pixelFormat < 0 || pixelFormat >= NUMPF)
-      throw new IllegalArgumentException("Invalid pixel format");
-  }
-
-  private static void checkSubsampling(int subsamp) {
-    if (subsamp < 0 || subsamp >= NUMSAMP)
-      throw new IllegalArgumentException("Invalid subsampling type");
-  }
-
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java
deleted file mode 100644
index 74e5db9..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * Copyright (C)2011-2015, 2018 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-import java.awt.image.*;
-import java.nio.*;
-import java.io.*;
-
-/**
- * TurboJPEG compressor
- */
-public class TJCompressor implements Closeable {
-
-  private static final String NO_ASSOC_ERROR =
-    "No source image is associated with this instance";
-
-  /**
-   * Create a TurboJPEG compressor instance.
-   */
-  public TJCompressor() throws TJException {
-    init();
-  }
-
-  /**
-   * Create a TurboJPEG compressor instance and associate the uncompressed
-   * source image stored in <code>srcImage</code> with the newly created
-   * instance.
-   *
-   * @param srcImage see {@link #setSourceImage} for description
-   *
-   * @param x see {@link #setSourceImage} for description
-   *
-   * @param y see {@link #setSourceImage} for description
-   *
-   * @param width see {@link #setSourceImage} for description
-   *
-   * @param pitch see {@link #setSourceImage} for description
-   *
-   * @param height see {@link #setSourceImage} for description
-   *
-   * @param pixelFormat pixel format of the source image (one of
-   * {@link TJ#PF_RGB TJ.PF_*})
-   */
-  public TJCompressor(byte[] srcImage, int x, int y, int width, int pitch,
-                      int height, int pixelFormat) throws TJException {
-    setSourceImage(srcImage, x, y, width, pitch, height, pixelFormat);
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #TJCompressor(byte[], int, int, int, int, int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public TJCompressor(byte[] srcImage, int width, int pitch, int height,
-                      int pixelFormat) throws TJException {
-    setSourceImage(srcImage, width, pitch, height, pixelFormat);
-  }
-
-  /**
-   * Create a TurboJPEG compressor instance and associate the uncompressed
-   * source image stored in <code>srcImage</code> with the newly created
-   * instance.
-   *
-   * @param srcImage see
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
-   *
-   * @param x see
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
-   *
-   * @param y see
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
-   *
-   * @param width see
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
-   *
-   * @param height see
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} for description
-   */
-  public TJCompressor(BufferedImage srcImage, int x, int y, int width,
-                      int height) throws TJException {
-    setSourceImage(srcImage, x, y, width, height);
-  }
-
-  /**
-   * Associate an uncompressed RGB, grayscale, or CMYK source image with this
-   * compressor instance.
-   *
-   * @param srcImage image buffer containing RGB, grayscale, or CMYK pixels to
-   * be compressed or encoded.  This buffer is not modified.
-   *
-   * @param x x offset (in pixels) of the region in the source image from which
-   * the JPEG or YUV image should be compressed/encoded
-   *
-   * @param y y offset (in pixels) of the region in the source image from which
-   * the JPEG or YUV image should be compressed/encoded
-   *
-   * @param width width (in pixels) of the region in the source image from
-   * which the JPEG or YUV image should be compressed/encoded
-   *
-   * @param pitch bytes per line of the source image.  Normally, this should be
-   * <code>width * TJ.pixelSize(pixelFormat)</code> if the source image is
-   * unpadded, but you can use this parameter to, for instance, specify that
-   * the scanlines in the source image are padded to a 4-byte boundary or to
-   * compress/encode a JPEG or YUV image from a region of a larger source
-   * image.  You can also be clever and use this parameter to skip lines, etc.
-   * Setting this parameter to 0 is the equivalent of setting it to
-   * <code>width * TJ.pixelSize(pixelFormat)</code>.
-   *
-   * @param height height (in pixels) of the region in the source image from
-   * which the JPEG or YUV image should be compressed/encoded
-   *
-   * @param pixelFormat pixel format of the source image (one of
-   * {@link TJ#PF_RGB TJ.PF_*})
-   */
-  public void setSourceImage(byte[] srcImage, int x, int y, int width,
-                             int pitch, int height, int pixelFormat)
-                             throws TJException {
-    if (handle == 0) init();
-    if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
-        pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
-      throw new IllegalArgumentException("Invalid argument in setSourceImage()");
-    srcBuf = srcImage;
-    srcWidth = width;
-    if (pitch == 0)
-      srcPitch = width * TJ.getPixelSize(pixelFormat);
-    else
-      srcPitch = pitch;
-    srcHeight = height;
-    srcPixelFormat = pixelFormat;
-    srcX = x;
-    srcY = y;
-    srcBufInt = null;
-    srcYUVImage = null;
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #setSourceImage(byte[], int, int, int, int, int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void setSourceImage(byte[] srcImage, int width, int pitch,
-                             int height, int pixelFormat) throws TJException {
-    setSourceImage(srcImage, 0, 0, width, pitch, height, pixelFormat);
-    srcX = srcY = -1;
-  }
-
-  /**
-   * Associate an uncompressed RGB or grayscale source image with this
-   * compressor instance.
-   *
-   * @param srcImage a <code>BufferedImage</code> instance containing RGB or
-   * grayscale pixels to be compressed or encoded.  This image is not modified.
-   *
-   * @param x x offset (in pixels) of the region in the source image from which
-   * the JPEG or YUV image should be compressed/encoded
-   *
-   * @param y y offset (in pixels) of the region in the source image from which
-   * the JPEG or YUV image should be compressed/encoded
-   *
-   * @param width width (in pixels) of the region in the source image from
-   * which the JPEG or YUV image should be compressed/encoded (0 = use the
-   * width of the source image)
-   *
-   * @param height height (in pixels) of the region in the source image from
-   * which the JPEG or YUV image should be compressed/encoded (0 = use the
-   * height of the source image)
-   */
-  public void setSourceImage(BufferedImage srcImage, int x, int y, int width,
-                             int height) throws TJException {
-    if (handle == 0) init();
-    if (srcImage == null || x < 0 || y < 0 || width < 0 || height < 0)
-      throw new IllegalArgumentException("Invalid argument in setSourceImage()");
-    srcX = x;
-    srcY = y;
-    srcWidth = (width == 0) ? srcImage.getWidth() : width;
-    srcHeight = (height == 0) ? srcImage.getHeight() : height;
-    if (x + width > srcImage.getWidth() || y + height > srcImage.getHeight())
-      throw new IllegalArgumentException("Compression region exceeds the bounds of the source image");
-
-    int pixelFormat;
-    boolean intPixels = false;
-    if (byteOrder == null)
-      byteOrder = ByteOrder.nativeOrder();
-    switch (srcImage.getType()) {
-    case BufferedImage.TYPE_3BYTE_BGR:
-      pixelFormat = TJ.PF_BGR;  break;
-    case BufferedImage.TYPE_4BYTE_ABGR:
-    case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-      pixelFormat = TJ.PF_XBGR;  break;
-    case BufferedImage.TYPE_BYTE_GRAY:
-      pixelFormat = TJ.PF_GRAY;  break;
-    case BufferedImage.TYPE_INT_BGR:
-      if (byteOrder == ByteOrder.BIG_ENDIAN)
-        pixelFormat = TJ.PF_XBGR;
-      else
-        pixelFormat = TJ.PF_RGBX;
-      intPixels = true;  break;
-    case BufferedImage.TYPE_INT_RGB:
-    case BufferedImage.TYPE_INT_ARGB:
-    case BufferedImage.TYPE_INT_ARGB_PRE:
-      if (byteOrder == ByteOrder.BIG_ENDIAN)
-        pixelFormat = TJ.PF_XRGB;
-      else
-        pixelFormat = TJ.PF_BGRX;
-      intPixels = true;  break;
-    default:
-      throw new IllegalArgumentException("Unsupported BufferedImage format");
-    }
-    srcPixelFormat = pixelFormat;
-
-    WritableRaster wr = srcImage.getRaster();
-    if (intPixels) {
-      SinglePixelPackedSampleModel sm =
-        (SinglePixelPackedSampleModel)srcImage.getSampleModel();
-      srcStride = sm.getScanlineStride();
-      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
-      srcBufInt = db.getData();
-      srcBuf = null;
-    } else {
-      ComponentSampleModel sm =
-        (ComponentSampleModel)srcImage.getSampleModel();
-      int pixelSize = sm.getPixelStride();
-      if (pixelSize != TJ.getPixelSize(pixelFormat))
-        throw new IllegalArgumentException("Inconsistency between pixel format and pixel size in BufferedImage");
-      srcPitch = sm.getScanlineStride();
-      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
-      srcBuf = db.getData();
-      srcBufInt = null;
-    }
-    srcYUVImage = null;
-  }
-
-  /**
-   * Associate an uncompressed YUV planar source image with this compressor
-   * instance.
-   *
-   * @param srcImage YUV planar image to be compressed.  This image is not
-   * modified.
-   */
-  public void setSourceImage(YUVImage srcImage) throws TJException {
-    if (handle == 0) init();
-    if (srcImage == null)
-      throw new IllegalArgumentException("Invalid argument in setSourceImage()");
-    srcYUVImage = srcImage;
-    srcBuf = null;
-    srcBufInt = null;
-  }
-
-  /**
-   * Set the level of chrominance subsampling for subsequent compress/encode
-   * operations.  When pixels are converted from RGB to YCbCr (see
-   * {@link TJ#CS_YCbCr}) or from CMYK to YCCK (see {@link TJ#CS_YCCK}) as part
-   * of the JPEG compression process, some of the Cb and Cr (chrominance)
-   * components can be discarded or averaged together to produce a smaller
-   * image with little perceptible loss of image clarity (the human eye is more
-   * sensitive to small changes in brightness than to small changes in color.)
-   * This is called "chrominance subsampling".
-   * <p>
-   * NOTE: This method has no effect when compressing a JPEG image from a YUV
-   * planar source.  In that case, the level of chrominance subsampling in
-   * the JPEG image is determined by the source.  Furthermore, this method has
-   * no effect when encoding to a pre-allocated {@link YUVImage} instance.  In
-   * that case, the level of chrominance subsampling is determined by the
-   * destination.
-   *
-   * @param newSubsamp the level of chrominance subsampling to use in
-   * subsequent compress/encode oeprations (one of
-   * {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public void setSubsamp(int newSubsamp) {
-    if (newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP)
-      throw new IllegalArgumentException("Invalid argument in setSubsamp()");
-    subsamp = newSubsamp;
-  }
-
-  /**
-   * Set the JPEG image quality level for subsequent compress operations.
-   *
-   * @param quality the new JPEG image quality level (1 to 100, 1 = worst,
-   * 100 = best)
-   */
-  public void setJPEGQuality(int quality) {
-    if (quality < 1 || quality > 100)
-      throw new IllegalArgumentException("Invalid argument in setJPEGQuality()");
-    jpegQuality = quality;
-  }
-
-  /**
-   * Compress the uncompressed source image associated with this compressor
-   * instance and output a JPEG image to the given destination buffer.
-   *
-   * @param dstBuf buffer that will receive the JPEG image.  Use
-   * {@link TJ#bufSize} to determine the maximum size for this buffer based on
-   * the source image's width and height and the desired level of chrominance
-   * subsampling.
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void compress(byte[] dstBuf, int flags) throws TJException {
-    if (dstBuf == null || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in compress()");
-    if (srcBuf == null && srcBufInt == null && srcYUVImage == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (jpegQuality < 0)
-      throw new IllegalStateException("JPEG Quality not set");
-    if (subsamp < 0 && srcYUVImage == null)
-      throw new IllegalStateException("Subsampling level not set");
-
-    if (srcYUVImage != null)
-      compressedSize = compressFromYUV(srcYUVImage.getPlanes(),
-                                       srcYUVImage.getOffsets(),
-                                       srcYUVImage.getWidth(),
-                                       srcYUVImage.getStrides(),
-                                       srcYUVImage.getHeight(),
-                                       srcYUVImage.getSubsamp(),
-                                       dstBuf, jpegQuality, flags);
-    else if (srcBuf != null) {
-      if (srcX >= 0 && srcY >= 0)
-        compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch,
-                                  srcHeight, srcPixelFormat, dstBuf, subsamp,
-                                  jpegQuality, flags);
-      else
-        compressedSize = compress(srcBuf, srcWidth, srcPitch, srcHeight,
-                                  srcPixelFormat, dstBuf, subsamp, jpegQuality,
-                                  flags);
-    } else if (srcBufInt != null) {
-      if (srcX >= 0 && srcY >= 0)
-        compressedSize = compress(srcBufInt, srcX, srcY, srcWidth, srcStride,
-                                  srcHeight, srcPixelFormat, dstBuf, subsamp,
-                                  jpegQuality, flags);
-      else
-        compressedSize = compress(srcBufInt, srcWidth, srcStride, srcHeight,
-                                  srcPixelFormat, dstBuf, subsamp, jpegQuality,
-                                  flags);
-    }
-  }
-
-  /**
-   * Compress the uncompressed source image associated with this compressor
-   * instance and return a buffer containing a JPEG image.
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a buffer containing a JPEG image.  The length of this buffer will
-   * not be equal to the size of the JPEG image.  Use {@link
-   * #getCompressedSize} to obtain the size of the JPEG image.
-   */
-  public byte[] compress(int flags) throws TJException {
-    checkSourceImage();
-    byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
-    compress(buf, flags);
-    return buf;
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
-   * {@link #compress(byte[], int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void compress(BufferedImage srcImage, byte[] dstBuf, int flags)
-                       throws TJException {
-    setSourceImage(srcImage, 0, 0, 0, 0);
-    compress(dstBuf, flags);
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
-   * {@link #compress(int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public byte[] compress(BufferedImage srcImage, int flags)
-                         throws TJException {
-    setSourceImage(srcImage, 0, 0, 0, 0);
-    return compress(flags);
-  }
-
-  /**
-   * Encode the uncompressed source image associated with this compressor
-   * instance into a YUV planar image and store it in the given
-   * <code>YUVImage</code> instance.   This method uses the accelerated color
-   * conversion routines in TurboJPEG's underlying codec but does not execute
-   * any of the other steps in the JPEG compression process.  Encoding
-   * CMYK source images to YUV is not supported.
-   *
-   * @param dstImage {@link YUVImage} instance that will receive the YUV planar
-   * image
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void encodeYUV(YUVImage dstImage, int flags) throws TJException {
-    if (dstImage == null || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in encodeYUV()");
-    if (srcBuf == null && srcBufInt == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (srcYUVImage != null)
-      throw new IllegalStateException("Source image is not correct type");
-    checkSubsampling();
-    if (srcWidth != dstImage.getWidth() || srcHeight != dstImage.getHeight())
-      throw new IllegalStateException("Destination image is the wrong size");
-
-    if (srcBufInt != null) {
-      encodeYUV(srcBufInt, srcX, srcY, srcWidth, srcStride, srcHeight,
-                srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
-                dstImage.getStrides(), dstImage.getSubsamp(), flags);
-    } else {
-      encodeYUV(srcBuf, srcX, srcY, srcWidth, srcPitch, srcHeight,
-                srcPixelFormat, dstImage.getPlanes(), dstImage.getOffsets(),
-                dstImage.getStrides(), dstImage.getSubsamp(), flags);
-    }
-    compressedSize = 0;
-  }
-
-  /**
-   * @deprecated Use {@link #encodeYUV(YUVImage, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void encodeYUV(byte[] dstBuf, int flags) throws TJException {
-    if (dstBuf == null)
-      throw new IllegalArgumentException("Invalid argument in encodeYUV()");
-    checkSourceImage();
-    checkSubsampling();
-    YUVImage dstYUVImage = new YUVImage(dstBuf, srcWidth, 4, srcHeight,
-                                        subsamp);
-    encodeYUV(dstYUVImage, flags);
-  }
-
-  /**
-   * Encode the uncompressed source image associated with this compressor
-   * instance into a unified YUV planar image buffer and return a
-   * <code>YUVImage</code> instance containing the encoded image.  This method
-   * uses the accelerated color conversion routines in TurboJPEG's underlying
-   * codec but does not execute any of the other steps in the JPEG compression
-   * process.  Encoding CMYK source images to YUV is not supported.
-   *
-   * @param pad the width of each line in each plane of the YUV image will be
-   * padded to the nearest multiple of this number of bytes (must be a power of
-   * 2.)
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a YUV planar image.
-   */
-  public YUVImage encodeYUV(int pad, int flags) throws TJException {
-    checkSourceImage();
-    checkSubsampling();
-    if (pad < 1 || ((pad & (pad - 1)) != 0))
-      throw new IllegalStateException("Invalid argument in encodeYUV()");
-    YUVImage dstYUVImage = new YUVImage(srcWidth, pad, srcHeight, subsamp);
-    encodeYUV(dstYUVImage, flags);
-    return dstYUVImage;
-  }
-
-  /**
-   * Encode the uncompressed source image associated with this compressor
-   * instance into separate Y, U (Cb), and V (Cr) image planes and return a
-   * <code>YUVImage</code> instance containing the encoded image planes.  This
-   * method uses the accelerated color conversion routines in TurboJPEG's
-   * underlying codec but does not execute any of the other steps in the JPEG
-   * compression process.  Encoding CMYK source images to YUV is not supported.
-   *
-   * @param strides an array of integers, each specifying the number of bytes
-   * per line in the corresponding plane of the output image.  Setting the
-   * stride for any plane to 0 is the same as setting it to the component width
-   * of the plane.  If <code>strides</code> is null, then the strides for all
-   * planes will be set to their respective component widths.  You can adjust
-   * the strides in order to add an arbitrary amount of line padding to each
-   * plane.
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a YUV planar image.
-   */
-  public YUVImage encodeYUV(int[] strides, int flags) throws TJException {
-    checkSourceImage();
-    checkSubsampling();
-    YUVImage dstYUVImage = new YUVImage(srcWidth, strides, srcHeight, subsamp);
-    encodeYUV(dstYUVImage, flags);
-    return dstYUVImage;
-  }
-
-  /**
-   * @deprecated Use {@link #encodeYUV(int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public byte[] encodeYUV(int flags) throws TJException {
-    checkSourceImage();
-    checkSubsampling();
-    YUVImage dstYUVImage = new YUVImage(srcWidth, 4, srcHeight, subsamp);
-    encodeYUV(dstYUVImage, flags);
-    return dstYUVImage.getBuf();
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
-   * {@link #encodeYUV(byte[], int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags)
-                        throws TJException {
-    setSourceImage(srcImage, 0, 0, 0, 0);
-    encodeYUV(dstBuf, flags);
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #setSourceImage(BufferedImage, int, int, int, int)} and
-   * {@link #encodeYUV(int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public byte[] encodeYUV(BufferedImage srcImage, int flags)
-                          throws TJException {
-    setSourceImage(srcImage, 0, 0, 0, 0);
-    return encodeYUV(flags);
-  }
-
-  /**
-   * Returns the size of the image (in bytes) generated by the most recent
-   * compress operation.
-   *
-   * @return the size of the image (in bytes) generated by the most recent
-   * compress operation.
-   */
-  public int getCompressedSize() {
-    return compressedSize;
-  }
-
-  /**
-   * Free the native structures associated with this compressor instance.
-   */
-  @Override
-  public void close() throws TJException {
-    if (handle != 0)
-      destroy();
-  }
-
-  @SuppressWarnings("checkstyle:DesignForExtension")
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      close();
-    } catch (TJException e) {
-    } finally {
-      super.finalize();
-    }
-  };
-
-  private native void init() throws TJException;
-
-  private native void destroy() throws TJException;
-
-  // JPEG size in bytes is returned
-  @SuppressWarnings("checkstyle:HiddenField")
-  @Deprecated
-  private native int compress(byte[] srcBuf, int width, int pitch,
-    int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
-    int flags) throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  private native int compress(byte[] srcBuf, int x, int y, int width,
-    int pitch, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
-    int jpegQual, int flags) throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  @Deprecated
-  private native int compress(int[] srcBuf, int width, int stride,
-    int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp, int jpegQual,
-    int flags) throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  private native int compress(int[] srcBuf, int x, int y, int width,
-    int stride, int height, int pixelFormat, byte[] jpegBuf, int jpegSubsamp,
-    int jpegQual, int flags) throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  private native int compressFromYUV(byte[][] srcPlanes, int[] srcOffsets,
-    int width, int[] srcStrides, int height, int subsamp, byte[] jpegBuf,
-    int jpegQual, int flags)
-    throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  @Deprecated
-  private native void encodeYUV(byte[] srcBuf, int width, int pitch,
-    int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
-    throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  private native void encodeYUV(byte[] srcBuf, int x, int y, int width,
-    int pitch, int height, int pixelFormat, byte[][] dstPlanes,
-    int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
-    throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  @Deprecated
-  private native void encodeYUV(int[] srcBuf, int width, int stride,
-    int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags)
-    throws TJException;
-
-  @SuppressWarnings("checkstyle:HiddenField")
-  private native void encodeYUV(int[] srcBuf, int x, int y, int width,
-    int srcStride, int height, int pixelFormat, byte[][] dstPlanes,
-    int[] dstOffsets, int[] dstStrides, int subsamp, int flags)
-    throws TJException;
-
-  static {
-    TJLoader.load();
-  }
-
-  private void checkSourceImage() {
-    if (srcWidth < 1 || srcHeight < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-  }
-
-  private void checkSubsampling() {
-    if (subsamp < 0)
-      throw new IllegalStateException("Subsampling level not set");
-  }
-
-  private long handle = 0;
-  private byte[] srcBuf = null;
-  private int[] srcBufInt = null;
-  private int srcWidth = 0;
-  private int srcHeight = 0;
-  private int srcX = -1;
-  private int srcY = -1;
-  private int srcPitch = 0;
-  private int srcStride = 0;
-  private int srcPixelFormat = -1;
-  private YUVImage srcYUVImage = null;
-  private int subsamp = -1;
-  private int jpegQuality = -1;
-  private int compressedSize = 0;
-  private int yuvPad = 4;
-  private ByteOrder byteOrder = null;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
deleted file mode 100644
index 9a34587..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C)2011, 2013 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-import java.awt.*;
-import java.nio.*;
-
-/**
- * Custom filter callback interface
- */
-public interface TJCustomFilter {
-
-  /**
-   * A callback function that can be used to modify the DCT coefficients after
-   * they are losslessly transformed but before they are transcoded to a new
-   * JPEG image.  This allows for custom filters or other transformations to be
-   * applied in the frequency domain.
-   *
-   * @param coeffBuffer a buffer containing transformed DCT coefficients.
-   * (NOTE: this buffer is not guaranteed to be valid once the callback
-   * returns, so applications wishing to hand off the DCT coefficients to
-   * another function or library should make a copy of them within the body of
-   * the callback.)
-   *
-   * @param bufferRegion rectangle containing the width and height of
-   * <code>coeffBuffer</code> as well as its offset relative to the component
-   * plane.  TurboJPEG implementations may choose to split each component plane
-   * into multiple DCT coefficient buffers and call the callback function once
-   * for each buffer.
-   *
-   * @param planeRegion rectangle containing the width and height of the
-   * component plane to which <code>coeffBuffer</code> belongs
-   *
-   * @param componentID ID number of the component plane to which
-   * <code>coeffBuffer</code> belongs (Y, Cb, and Cr have, respectively, ID's
-   * of 0, 1, and 2 in typical JPEG images.)
-   *
-   * @param transformID ID number of the transformed image to which
-   * <code>coeffBuffer</code> belongs.  This is the same as the index of the
-   * transform in the <code>transforms</code> array that was passed to {@link
-   * TJTransformer#transform TJTransformer.transform()}.
-   *
-   * @param transform a {@link TJTransform} instance that specifies the
-   * parameters and/or cropping region for this transform
-   */
-  void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
-                    Rectangle planeRegion, int componentID, int transformID,
-                    TJTransform transform)
-    throws TJException;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
deleted file mode 100644
index cba9ff0..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * Copyright (C)2011-2015, 2018 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-import java.awt.image.*;
-import java.nio.*;
-import java.io.*;
-
-/**
- * TurboJPEG decompressor
- */
-public class TJDecompressor implements Closeable {
-
-  private static final String NO_ASSOC_ERROR =
-    "No JPEG image is associated with this instance";
-
-  /**
-   * Create a TurboJPEG decompresssor instance.
-   */
-  public TJDecompressor() throws TJException {
-    init();
-  }
-
-  /**
-   * Create a TurboJPEG decompressor instance and associate the JPEG source
-   * image stored in <code>jpegImage</code> with the newly created instance.
-   *
-   * @param jpegImage JPEG image buffer (size of the JPEG image is assumed to
-   * be the length of the array.)  This buffer is not modified.
-   */
-  public TJDecompressor(byte[] jpegImage) throws TJException {
-    init();
-    setSourceImage(jpegImage, jpegImage.length);
-  }
-
-  /**
-   * Create a TurboJPEG decompressor instance and associate the JPEG source
-   * image of length <code>imageSize</code> bytes stored in
-   * <code>jpegImage</code> with the newly created instance.
-   *
-   * @param jpegImage JPEG image buffer.  This buffer is not modified.
-   *
-   * @param imageSize size of the JPEG image (in bytes)
-   */
-  public TJDecompressor(byte[] jpegImage, int imageSize) throws TJException {
-    init();
-    setSourceImage(jpegImage, imageSize);
-  }
-
-  /**
-   * Create a TurboJPEG decompressor instance and associate the YUV planar
-   * source image stored in <code>yuvImage</code> with the newly created
-   * instance.
-   *
-   * @param yuvImage {@link YUVImage} instance containing a YUV planar
-   * image to be decoded.  This image is not modified.
-   */
-  @SuppressWarnings("checkstyle:HiddenField")
-  public TJDecompressor(YUVImage yuvImage) throws TJException {
-    init();
-    setSourceImage(yuvImage);
-  }
-
-  /**
-   * Associate the JPEG image of length <code>imageSize</code> bytes stored in
-   * <code>jpegImage</code> with this decompressor instance.  This image will
-   * be used as the source image for subsequent decompress operations.
-   *
-   * @param jpegImage JPEG image buffer.  This buffer is not modified.
-   *
-   * @param imageSize size of the JPEG image (in bytes)
-   */
-  public void setSourceImage(byte[] jpegImage, int imageSize)
-                             throws TJException {
-    if (jpegImage == null || imageSize < 1)
-      throw new IllegalArgumentException("Invalid argument in setSourceImage()");
-    jpegBuf = jpegImage;
-    jpegBufSize = imageSize;
-    decompressHeader(jpegBuf, jpegBufSize);
-    yuvImage = null;
-  }
-
-  /**
-   * @deprecated Use {@link #setSourceImage(byte[], int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void setJPEGImage(byte[] jpegImage, int imageSize)
-                           throws TJException {
-    setSourceImage(jpegImage, imageSize);
-  }
-
-  /**
-   * Associate the specified YUV planar source image with this decompressor
-   * instance.  Subsequent decompress operations will decode this image into an
-   * RGB or grayscale destination image.
-   *
-   * @param srcImage {@link YUVImage} instance containing a YUV planar image to
-   * be decoded.  This image is not modified.
-   */
-  public void setSourceImage(YUVImage srcImage) {
-    if (srcImage == null)
-      throw new IllegalArgumentException("Invalid argument in setSourceImage()");
-    yuvImage = srcImage;
-    jpegBuf = null;
-    jpegBufSize = 0;
-  }
-
-
-  /**
-   * Returns the width of the source image (JPEG or YUV) associated with this
-   * decompressor instance.
-   *
-   * @return the width of the source image (JPEG or YUV) associated with this
-   * decompressor instance.
-   */
-  public int getWidth() {
-    if (yuvImage != null)
-      return yuvImage.getWidth();
-    if (jpegWidth < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return jpegWidth;
-  }
-
-  /**
-   * Returns the height of the source image (JPEG or YUV) associated with this
-   * decompressor instance.
-   *
-   * @return the height of the source image (JPEG or YUV) associated with this
-   * decompressor instance.
-   */
-  public int getHeight() {
-    if (yuvImage != null)
-      return yuvImage.getHeight();
-    if (jpegHeight < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return jpegHeight;
-  }
-
-  /**
-   * Returns the level of chrominance subsampling used in the source image
-   * (JPEG or YUV) associated with this decompressor instance.  See
-   * {@link TJ#SAMP_444 TJ.SAMP_*}.
-   *
-   * @return the level of chrominance subsampling used in the source image
-   * (JPEG or YUV) associated with this decompressor instance.
-   */
-  public int getSubsamp() {
-    if (yuvImage != null)
-      return yuvImage.getSubsamp();
-    if (jpegSubsamp < 0)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (jpegSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException("JPEG header information is invalid");
-    return jpegSubsamp;
-  }
-
-  /**
-   * Returns the colorspace used in the source image (JPEG or YUV) associated
-   * with this decompressor instance.  See {@link TJ#CS_RGB TJ.CS_*}.  If the
-   * source image is YUV, then this always returns {@link TJ#CS_YCbCr}.
-   *
-   * @return the colorspace used in the source image (JPEG or YUV) associated
-   * with this decompressor instance.
-   */
-  public int getColorspace() {
-    if (yuvImage != null)
-      return TJ.CS_YCbCr;
-    if (jpegColorspace < 0)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (jpegColorspace >= TJ.NUMCS)
-      throw new IllegalStateException("JPEG header information is invalid");
-    return jpegColorspace;
-  }
-
-  /**
-   * Returns the JPEG image buffer associated with this decompressor instance.
-   *
-   * @return the JPEG image buffer associated with this decompressor instance.
-   */
-  public byte[] getJPEGBuf() {
-    if (jpegBuf == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return jpegBuf;
-  }
-
-  /**
-   * Returns the size of the JPEG image (in bytes) associated with this
-   * decompressor instance.
-   *
-   * @return the size of the JPEG image (in bytes) associated with this
-   * decompressor instance.
-   */
-  public int getJPEGSize() {
-    if (jpegBufSize < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return jpegBufSize;
-  }
-
-  /**
-   * Returns the width of the largest scaled-down image that the TurboJPEG
-   * decompressor can generate without exceeding the desired image width and
-   * height.
-   *
-   * @param desiredWidth desired width (in pixels) of the decompressed image.
-   * Setting this to 0 is the same as setting it to the width of the JPEG image
-   * (in other words, the width will not be considered when determining the
-   * scaled image size.)
-   *
-   * @param desiredHeight desired height (in pixels) of the decompressed image.
-   * Setting this to 0 is the same as setting it to the height of the JPEG
-   * image (in other words, the height will not be considered when determining
-   * the scaled image size.)
-   *
-   * @return the width of the largest scaled-down image that the TurboJPEG
-   * decompressor can generate without exceeding the desired image width and
-   * height.
-   */
-  public int getScaledWidth(int desiredWidth, int desiredHeight) {
-    if (jpegWidth < 1 || jpegHeight < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (desiredWidth < 0 || desiredHeight < 0)
-      throw new IllegalArgumentException("Invalid argument in getScaledWidth()");
-    TJScalingFactor[] sf = TJ.getScalingFactors();
-    if (desiredWidth == 0)
-      desiredWidth = jpegWidth;
-    if (desiredHeight == 0)
-      desiredHeight = jpegHeight;
-    int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
-    for (int i = 0; i < sf.length; i++) {
-      scaledWidth = sf[i].getScaled(jpegWidth);
-      scaledHeight = sf[i].getScaled(jpegHeight);
-      if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
-        break;
-    }
-    if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
-      throw new IllegalArgumentException("Could not scale down to desired image dimensions");
-    return scaledWidth;
-  }
-
-  /**
-   * Returns the height of the largest scaled-down image that the TurboJPEG
-   * decompressor can generate without exceeding the desired image width and
-   * height.
-   *
-   * @param desiredWidth desired width (in pixels) of the decompressed image.
-   * Setting this to 0 is the same as setting it to the width of the JPEG image
-   * (in other words, the width will not be considered when determining the
-   * scaled image size.)
-   *
-   * @param desiredHeight desired height (in pixels) of the decompressed image.
-   * Setting this to 0 is the same as setting it to the height of the JPEG
-   * image (in other words, the height will not be considered when determining
-   * the scaled image size.)
-   *
-   * @return the height of the largest scaled-down image that the TurboJPEG
-   * decompressor can generate without exceeding the desired image width and
-   * height.
-   */
-  public int getScaledHeight(int desiredWidth, int desiredHeight) {
-    if (jpegWidth < 1 || jpegHeight < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (desiredWidth < 0 || desiredHeight < 0)
-      throw new IllegalArgumentException("Invalid argument in getScaledHeight()");
-    TJScalingFactor[] sf = TJ.getScalingFactors();
-    if (desiredWidth == 0)
-      desiredWidth = jpegWidth;
-    if (desiredHeight == 0)
-      desiredHeight = jpegHeight;
-    int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
-    for (int i = 0; i < sf.length; i++) {
-      scaledWidth = sf[i].getScaled(jpegWidth);
-      scaledHeight = sf[i].getScaled(jpegHeight);
-      if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
-        break;
-    }
-    if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
-      throw new IllegalArgumentException("Could not scale down to desired image dimensions");
-    return scaledHeight;
-  }
-
-  /**
-   * Decompress the JPEG source image or decode the YUV source image associated
-   * with this decompressor instance and output a grayscale, RGB, or CMYK image
-   * to the given destination buffer.
-   * <p>
-   * NOTE: The output image is fully recoverable if this method throws a
-   * non-fatal {@link TJException} (unless
-   * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
-   *
-   * @param dstBuf buffer that will receive the decompressed/decoded image.
-   * If the source image is a JPEG image, then this buffer should normally be
-   * <code>pitch * scaledHeight</code> bytes in size, where
-   * <code>scaledHeight</code> can be determined by calling <code>
-   * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegHeight)
-   * </code> with one of the scaling factors returned from {@link
-   * TJ#getScalingFactors} or by calling {@link #getScaledHeight}.  If the
-   * source image is a YUV image, then this buffer should normally be
-   * <code>pitch * height</code> bytes in size, where <code>height</code> is
-   * the height of the YUV image.  However, the buffer may also be larger than
-   * the dimensions of the source image, in which case the <code>x</code>,
-   * <code>y</code>, and <code>pitch</code> parameters can be used to specify
-   * the region into which the source image should be decompressed/decoded.
-   *
-   * @param x x offset (in pixels) of the region in the destination image into
-   * which the source image should be decompressed/decoded
-   *
-   * @param y y offset (in pixels) of the region in the destination image into
-   * which the source image should be decompressed/decoded
-   *
-   * @param desiredWidth If the source image is a JPEG image, then this
-   * specifies the desired width (in pixels) of the decompressed image (or
-   * image region.)  If the desired destination image dimensions are different
-   * than the source image dimensions, then TurboJPEG will use scaling in the
-   * JPEG decompressor to generate the largest possible image that will fit
-   * within the desired dimensions.  Setting this to 0 is the same as setting
-   * it to the width of the JPEG image (in other words, the width will not be
-   * considered when determining the scaled image size.)  This parameter is
-   * ignored if the source image is a YUV image.
-   *
-   * @param pitch bytes per line of the destination image.  Normally, this
-   * should be set to <code>scaledWidth * TJ.pixelSize(pixelFormat)</code> if
-   * the destination image is unpadded, but you can use this to, for instance,
-   * pad each line of the destination image to a 4-byte boundary or to
-   * decompress/decode the source image into a region of a larger image.  NOTE:
-   * if the source image is a JPEG image, then <code>scaledWidth</code> can be
-   * determined by calling <code>
-   * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegWidth)
-   * </code> or by calling {@link #getScaledWidth}.  If the source image is a
-   * YUV image, then <code>scaledWidth</code> is the width of the YUV image.
-   * Setting this parameter to 0 is the equivalent of setting it to
-   * <code>scaledWidth * TJ.pixelSize(pixelFormat)</code>.
-   *
-   * @param desiredHeight If the source image is a JPEG image, then this
-   * specifies the desired height (in pixels) of the decompressed image (or
-   * image region.)  If the desired destination image dimensions are different
-   * than the source image dimensions, then TurboJPEG will use scaling in the
-   * JPEG decompressor to generate the largest possible image that will fit
-   * within the desired dimensions.  Setting this to 0 is the same as setting
-   * it to the height of the JPEG image (in other words, the height will not be
-   * considered when determining the scaled image size.)  This parameter is
-   * ignored if the source image is a YUV image.
-   *
-   * @param pixelFormat pixel format of the decompressed/decoded image (one of
-   * {@link TJ#PF_RGB TJ.PF_*})
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void decompress(byte[] dstBuf, int x, int y, int desiredWidth,
-                         int pitch, int desiredHeight, int pixelFormat,
-                         int flags) throws TJException {
-    if (jpegBuf == null && yuvImage == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (dstBuf == null || x < 0 || y < 0 || pitch < 0 ||
-        (yuvImage != null && (desiredWidth < 0 || desiredHeight < 0)) ||
-        pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompress()");
-    if (yuvImage != null)
-      decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
-                yuvImage.getStrides(), yuvImage.getSubsamp(), dstBuf, x, y,
-                yuvImage.getWidth(), pitch, yuvImage.getHeight(), pixelFormat,
-                flags);
-    else {
-      if (x > 0 || y > 0)
-        decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, pitch,
-                   desiredHeight, pixelFormat, flags);
-      else
-        decompress(jpegBuf, jpegBufSize, dstBuf, desiredWidth, pitch,
-                   desiredHeight, pixelFormat, flags);
-    }
-  }
-
-  /**
-   * @deprecated Use
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void decompress(byte[] dstBuf, int desiredWidth, int pitch,
-                         int desiredHeight, int pixelFormat, int flags)
-                         throws TJException {
-    decompress(dstBuf, 0, 0, desiredWidth, pitch, desiredHeight, pixelFormat,
-               flags);
-  }
-
-  /**
-   * Decompress the JPEG source image associated with this decompressor
-   * instance and return a buffer containing the decompressed image.
-   *
-   * @param desiredWidth see
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)}
-   * for description
-   *
-   * @param pitch see
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)}
-   * for description
-   *
-   * @param desiredHeight see
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)}
-   * for description
-   *
-   * @param pixelFormat pixel format of the decompressed image (one of
-   * {@link TJ#PF_RGB TJ.PF_*})
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a buffer containing the decompressed image.
-   */
-  public byte[] decompress(int desiredWidth, int pitch, int desiredHeight,
-                           int pixelFormat, int flags) throws TJException {
-    if (pitch < 0 ||
-        (yuvImage == null && (desiredWidth < 0 || desiredHeight < 0)) ||
-        pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompress()");
-    int pixelSize = TJ.getPixelSize(pixelFormat);
-    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
-    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
-    if (pitch == 0)
-      pitch = scaledWidth * pixelSize;
-    byte[] buf = new byte[pitch * scaledHeight];
-    decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
-    return buf;
-  }
-
-  /**
-   * Decompress the JPEG source image associated with this decompressor
-   * instance into a YUV planar image and store it in the given
-   * <code>YUVImage</code> instance.  This method performs JPEG decompression
-   * but leaves out the color conversion step, so a planar YUV image is
-   * generated instead of an RGB or grayscale image.  This method cannot be
-   * used to decompress JPEG source images with the CMYK or YCCK colorspace.
-   * <p>
-   * NOTE: The YUV planar output image is fully recoverable if this method
-   * throws a non-fatal {@link TJException} (unless
-   * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
-   *
-   * @param dstImage {@link YUVImage} instance that will receive the YUV planar
-   * image.  The level of subsampling specified in this <code>YUVImage</code>
-   * instance must match that of the JPEG image, and the width and height
-   * specified in the <code>YUVImage</code> instance must match one of the
-   * scaled image sizes that TurboJPEG is capable of generating from the JPEG
-   * source image.
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void decompressToYUV(YUVImage dstImage, int flags)
-                              throws TJException {
-    if (jpegBuf == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (dstImage == null || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
-    int scaledWidth = getScaledWidth(dstImage.getWidth(),
-                                     dstImage.getHeight());
-    int scaledHeight = getScaledHeight(dstImage.getWidth(),
-                                       dstImage.getHeight());
-    if (scaledWidth != dstImage.getWidth() ||
-        scaledHeight != dstImage.getHeight())
-      throw new IllegalArgumentException("YUVImage dimensions do not match one of the scaled image sizes that TurboJPEG is capable of generating.");
-    if (jpegSubsamp != dstImage.getSubsamp())
-      throw new IllegalArgumentException("YUVImage subsampling level does not match that of the JPEG image");
-
-    decompressToYUV(jpegBuf, jpegBufSize, dstImage.getPlanes(),
-                    dstImage.getOffsets(), dstImage.getWidth(),
-                    dstImage.getStrides(), dstImage.getHeight(), flags);
-  }
-
-  /**
-   * @deprecated Use {@link #decompressToYUV(YUVImage, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public void decompressToYUV(byte[] dstBuf, int flags) throws TJException {
-    YUVImage dstYUVImage = new YUVImage(dstBuf, jpegWidth, 4, jpegHeight,
-                                        jpegSubsamp);
-    decompressToYUV(dstYUVImage, flags);
-  }
-
-  /**
-   * Decompress the JPEG source image associated with this decompressor
-   * instance into a set of Y, U (Cb), and V (Cr) image planes and return a
-   * <code>YUVImage</code> instance containing the decompressed image planes.
-   * This method performs JPEG decompression but leaves out the color
-   * conversion step, so a planar YUV image is generated instead of an RGB or
-   * grayscale image.  This method cannot be used to decompress JPEG source
-   * images with the CMYK or YCCK colorspace.
-   *
-   * @param desiredWidth desired width (in pixels) of the YUV image.  If the
-   * desired image dimensions are different than the dimensions of the JPEG
-   * image being decompressed, then TurboJPEG will use scaling in the JPEG
-   * decompressor to generate the largest possible image that will fit within
-   * the desired dimensions.  Setting this to 0 is the same as setting it to
-   * the width of the JPEG image (in other words, the width will not be
-   * considered when determining the scaled image size.)
-   *
-   * @param strides an array of integers, each specifying the number of bytes
-   * per line in the corresponding plane of the output image.  Setting the
-   * stride for any plane to 0 is the same as setting it to the scaled
-   * component width of the plane.  If <tt>strides</tt> is NULL, then the
-   * strides for all planes will be set to their respective scaled component
-   * widths.  You can adjust the strides in order to add an arbitrary amount of
-   * line padding to each plane.
-   *
-   * @param desiredHeight desired height (in pixels) of the YUV image.  If the
-   * desired image dimensions are different than the dimensions of the JPEG
-   * image being decompressed, then TurboJPEG will use scaling in the JPEG
-   * decompressor to generate the largest possible image that will fit within
-   * the desired dimensions.  Setting this to 0 is the same as setting it to
-   * the height of the JPEG image (in other words, the height will not be
-   * considered when determining the scaled image size.)
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a YUV planar image.
-   */
-  public YUVImage decompressToYUV(int desiredWidth, int[] strides,
-                                  int desiredHeight,
-                                  int flags) throws TJException {
-    if (flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
-    if (jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (jpegSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException("JPEG header information is invalid");
-    if (yuvImage != null)
-      throw new IllegalStateException("Source image is the wrong type");
-
-    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
-    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
-    YUVImage dstYUVImage = new YUVImage(scaledWidth, null, scaledHeight,
-                                        jpegSubsamp);
-    decompressToYUV(dstYUVImage, flags);
-    return dstYUVImage;
-  }
-
-  /**
-   * Decompress the JPEG source image associated with this decompressor
-   * instance into a unified YUV planar image buffer and return a
-   * <code>YUVImage</code> instance containing the decompressed image.  This
-   * method performs JPEG decompression but leaves out the color conversion
-   * step, so a planar YUV image is generated instead of an RGB or grayscale
-   * image.  This method cannot be used to decompress JPEG source images with
-   * the CMYK or YCCK colorspace.
-   *
-   * @param desiredWidth desired width (in pixels) of the YUV image.  If the
-   * desired image dimensions are different than the dimensions of the JPEG
-   * image being decompressed, then TurboJPEG will use scaling in the JPEG
-   * decompressor to generate the largest possible image that will fit within
-   * the desired dimensions.  Setting this to 0 is the same as setting it to
-   * the width of the JPEG image (in other words, the width will not be
-   * considered when determining the scaled image size.)
-   *
-   * @param pad the width of each line in each plane of the YUV image will be
-   * padded to the nearest multiple of this number of bytes (must be a power of
-   * 2.)
-   *
-   * @param desiredHeight desired height (in pixels) of the YUV image.  If the
-   * desired image dimensions are different than the dimensions of the JPEG
-   * image being decompressed, then TurboJPEG will use scaling in the JPEG
-   * decompressor to generate the largest possible image that will fit within
-   * the desired dimensions.  Setting this to 0 is the same as setting it to
-   * the height of the JPEG image (in other words, the height will not be
-   * considered when determining the scaled image size.)
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a YUV planar image.
-   */
-  public YUVImage decompressToYUV(int desiredWidth, int pad, int desiredHeight,
-                                  int flags) throws TJException {
-    if (flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompressToYUV()");
-    if (jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (jpegSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException("JPEG header information is invalid");
-    if (yuvImage != null)
-      throw new IllegalStateException("Source image is the wrong type");
-
-    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
-    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
-    YUVImage dstYUVImage = new YUVImage(scaledWidth, pad, scaledHeight,
-                                        jpegSubsamp);
-    decompressToYUV(dstYUVImage, flags);
-    return dstYUVImage;
-  }
-
-  /**
-   * @deprecated Use {@link #decompressToYUV(int, int, int, int)} instead.
-   */
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  @Deprecated
-  public byte[] decompressToYUV(int flags) throws TJException {
-    YUVImage dstYUVImage = new YUVImage(jpegWidth, 4, jpegHeight, jpegSubsamp);
-    decompressToYUV(dstYUVImage, flags);
-    return dstYUVImage.getBuf();
-  }
-
-  /**
-   * Decompress the JPEG source image or decode the YUV source image associated
-   * with this decompressor instance and output a grayscale, RGB, or CMYK image
-   * to the given destination buffer.
-   * <p>
-   * NOTE: The output image is fully recoverable if this method throws a
-   * non-fatal {@link TJException} (unless
-   * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
-   *
-   * @param dstBuf buffer that will receive the decompressed/decoded image.
-   * If the source image is a JPEG image, then this buffer should normally be
-   * <code>stride * scaledHeight</code> pixels in size, where
-   * <code>scaledHeight</code> can be determined by calling <code>
-   * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegHeight)
-   * </code> with one of the scaling factors returned from {@link
-   * TJ#getScalingFactors} or by calling {@link #getScaledHeight}.  If the
-   * source image is a YUV image, then this buffer should normally be
-   * <code>stride * height</code> pixels in size, where <code>height</code> is
-   * the height of the YUV image.  However, the buffer may also be larger than
-   * the dimensions of the JPEG image, in which case the <code>x</code>,
-   * <code>y</code>, and <code>stride</code> parameters can be used to specify
-   * the region into which the source image should be decompressed.
-   *
-   * @param x x offset (in pixels) of the region in the destination image into
-   * which the source image should be decompressed/decoded
-   *
-   * @param y y offset (in pixels) of the region in the destination image into
-   * which the source image should be decompressed/decoded
-   *
-   * @param desiredWidth If the source image is a JPEG image, then this
-   * specifies the desired width (in pixels) of the decompressed image (or
-   * image region.)  If the desired destination image dimensions are different
-   * than the source image dimensions, then TurboJPEG will use scaling in the
-   * JPEG decompressor to generate the largest possible image that will fit
-   * within the desired dimensions.  Setting this to 0 is the same as setting
-   * it to the width of the JPEG image (in other words, the width will not be
-   * considered when determining the scaled image size.)  This parameter is
-   * ignored if the source image is a YUV image.
-   *
-   * @param stride pixels per line of the destination image.  Normally, this
-   * should be set to <code>scaledWidth</code>, but you can use this to, for
-   * instance, decompress the JPEG image into a region of a larger image.
-   * NOTE: if the source image is a JPEG image, then <code>scaledWidth</code>
-   * can be determined by calling <code>
-   * scalingFactor.{@link TJScalingFactor#getScaled getScaled}(jpegWidth)
-   * </code> or by calling {@link #getScaledWidth}.  If the source image is a
-   * YUV image, then <code>scaledWidth</code> is the width of the YUV image.
-   * Setting this parameter to 0 is the equivalent of setting it to
-   * <code>scaledWidth</code>.
-   *
-   * @param desiredHeight If the source image is a JPEG image, then this
-   * specifies the desired height (in pixels) of the decompressed image (or
-   * image region.)  If the desired destination image dimensions are different
-   * than the source image dimensions, then TurboJPEG will use scaling in the
-   * JPEG decompressor to generate the largest possible image that will fit
-   * within the desired dimensions.  Setting this to 0 is the same as setting
-   * it to the height of the JPEG image (in other words, the height will not be
-   * considered when determining the scaled image size.)  This parameter is
-   * ignored if the source image is a YUV image.
-   *
-   * @param pixelFormat pixel format of the decompressed image (one of
-   * {@link TJ#PF_RGB TJ.PF_*})
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void decompress(int[] dstBuf, int x, int y, int desiredWidth,
-                         int stride, int desiredHeight, int pixelFormat,
-                         int flags) throws TJException {
-    if (jpegBuf == null && yuvImage == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (dstBuf == null || x < 0 || y < 0 || stride < 0 ||
-        (yuvImage != null && (desiredWidth < 0 || desiredHeight < 0)) ||
-        pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompress()");
-    if (yuvImage != null)
-      decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
-                yuvImage.getStrides(), yuvImage.getSubsamp(), dstBuf, x, y,
-                yuvImage.getWidth(), stride, yuvImage.getHeight(), pixelFormat,
-                flags);
-    else
-      decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, stride,
-                 desiredHeight, pixelFormat, flags);
-  }
-
-  /**
-   * Decompress the JPEG source image or decode the YUV source image associated
-   * with this decompressor instance and output a decompressed/decoded image to
-   * the given <code>BufferedImage</code> instance.
-   * <p>
-   * NOTE: The output image is fully recoverable if this method throws a
-   * non-fatal {@link TJException} (unless
-   * {@link TJ#FLAG_STOPONWARNING TJ.FLAG_STOPONWARNING} is specified.)
-   *
-   * @param dstImage a <code>BufferedImage</code> instance that will receive
-   * the decompressed/decoded image.  If the source image is a JPEG image, then
-   * the width and height of the <code>BufferedImage</code> instance must match
-   * one of the scaled image sizes that TurboJPEG is capable of generating from
-   * the JPEG image.  If the source image is a YUV image, then the width and
-   * height of the <code>BufferedImage</code> instance must match the width and
-   * height of the YUV image.
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void decompress(BufferedImage dstImage, int flags)
-                         throws TJException {
-    if (dstImage == null || flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompress()");
-    int desiredWidth = dstImage.getWidth();
-    int desiredHeight = dstImage.getHeight();
-    int scaledWidth, scaledHeight;
-
-    if (yuvImage != null) {
-      if (desiredWidth != yuvImage.getWidth() ||
-          desiredHeight != yuvImage.getHeight())
-        throw new IllegalArgumentException("BufferedImage dimensions do not match the dimensions of the source image.");
-      scaledWidth = yuvImage.getWidth();
-      scaledHeight = yuvImage.getHeight();
-    } else {
-      scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
-      scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
-      if (scaledWidth != desiredWidth || scaledHeight != desiredHeight)
-        throw new IllegalArgumentException("BufferedImage dimensions do not match one of the scaled image sizes that TurboJPEG is capable of generating.");
-    }
-    int pixelFormat;  boolean intPixels = false;
-    if (byteOrder == null)
-      byteOrder = ByteOrder.nativeOrder();
-    switch (dstImage.getType()) {
-    case BufferedImage.TYPE_3BYTE_BGR:
-      pixelFormat = TJ.PF_BGR;  break;
-    case BufferedImage.TYPE_4BYTE_ABGR:
-    case BufferedImage.TYPE_4BYTE_ABGR_PRE:
-      pixelFormat = TJ.PF_XBGR;  break;
-    case BufferedImage.TYPE_BYTE_GRAY:
-      pixelFormat = TJ.PF_GRAY;  break;
-    case BufferedImage.TYPE_INT_BGR:
-      if (byteOrder == ByteOrder.BIG_ENDIAN)
-        pixelFormat = TJ.PF_XBGR;
-      else
-        pixelFormat = TJ.PF_RGBX;
-      intPixels = true;  break;
-    case BufferedImage.TYPE_INT_RGB:
-      if (byteOrder == ByteOrder.BIG_ENDIAN)
-        pixelFormat = TJ.PF_XRGB;
-      else
-        pixelFormat = TJ.PF_BGRX;
-      intPixels = true;  break;
-    case BufferedImage.TYPE_INT_ARGB:
-    case BufferedImage.TYPE_INT_ARGB_PRE:
-      if (byteOrder == ByteOrder.BIG_ENDIAN)
-        pixelFormat = TJ.PF_ARGB;
-      else
-        pixelFormat = TJ.PF_BGRA;
-      intPixels = true;  break;
-    default:
-      throw new IllegalArgumentException("Unsupported BufferedImage format");
-    }
-    WritableRaster wr = dstImage.getRaster();
-    if (intPixels) {
-      SinglePixelPackedSampleModel sm =
-        (SinglePixelPackedSampleModel)dstImage.getSampleModel();
-      int stride = sm.getScanlineStride();
-      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
-      int[] buf = db.getData();
-      if (yuvImage != null)
-        decodeYUV(yuvImage.getPlanes(), yuvImage.getOffsets(),
-                  yuvImage.getStrides(), yuvImage.getSubsamp(), buf, 0, 0,
-                  yuvImage.getWidth(), stride, yuvImage.getHeight(),
-                  pixelFormat, flags);
-      else {
-        if (jpegBuf == null)
-          throw new IllegalStateException(NO_ASSOC_ERROR);
-        decompress(jpegBuf, jpegBufSize, buf, 0, 0, scaledWidth, stride,
-                   scaledHeight, pixelFormat, flags);
-      }
-    } else {
-      ComponentSampleModel sm =
-        (ComponentSampleModel)dstImage.getSampleModel();
-      int pixelSize = sm.getPixelStride();
-      if (pixelSize != TJ.getPixelSize(pixelFormat))
-        throw new IllegalArgumentException("Inconsistency between pixel format and pixel size in BufferedImage");
-      int pitch = sm.getScanlineStride();
-      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
-      byte[] buf = db.getData();
-      decompress(buf, 0, 0, scaledWidth, pitch, scaledHeight, pixelFormat,
-                 flags);
-    }
-  }
-
-  /**
-   * Decompress the JPEG source image or decode the YUV source image associated
-   * with this decompressor instance and return a <code>BufferedImage</code>
-   * instance containing the decompressed/decoded image.
-   *
-   * @param desiredWidth see
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)} for
-   * description
-   *
-   * @param desiredHeight see
-   * {@link #decompress(byte[], int, int, int, int, int, int, int)} for
-   * description
-   *
-   * @param bufferedImageType the image type of the <code>BufferedImage</code>
-   * instance that will be created (for instance,
-   * <code>BufferedImage.TYPE_INT_RGB</code>)
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return a <code>BufferedImage</code> instance containing the
-   * decompressed/decoded image.
-   */
-  public BufferedImage decompress(int desiredWidth, int desiredHeight,
-                                  int bufferedImageType, int flags)
-                                  throws TJException {
-    if ((yuvImage == null && (desiredWidth < 0 || desiredHeight < 0)) ||
-        flags < 0)
-      throw new IllegalArgumentException("Invalid argument in decompress()");
-    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
-    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
-    BufferedImage img = new BufferedImage(scaledWidth, scaledHeight,
-                                          bufferedImageType);
-    decompress(img, flags);
-    return img;
-  }
-
-  /**
-   * Free the native structures associated with this decompressor instance.
-   */
-  @Override
-  public void close() throws TJException {
-    if (handle != 0)
-      destroy();
-  }
-
-  @SuppressWarnings("checkstyle:DesignForExtension")
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      close();
-    } catch (TJException e) {
-    } finally {
-      super.finalize();
-    }
-  };
-
-  private native void init() throws TJException;
-
-  private native void destroy() throws TJException;
-
-  private native void decompressHeader(byte[] srcBuf, int size)
-    throws TJException;
-
-  @Deprecated
-  private native void decompress(byte[] srcBuf, int size, byte[] dstBuf,
-    int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
-    throws TJException;
-
-  private native void decompress(byte[] srcBuf, int size, byte[] dstBuf, int x,
-    int y, int desiredWidth, int pitch, int desiredHeight, int pixelFormat,
-    int flags) throws TJException;
-
-  @Deprecated
-  private native void decompress(byte[] srcBuf, int size, int[] dstBuf,
-    int desiredWidth, int stride, int desiredHeight, int pixelFormat,
-    int flags) throws TJException;
-
-  private native void decompress(byte[] srcBuf, int size, int[] dstBuf, int x,
-    int y, int desiredWidth, int stride, int desiredHeight, int pixelFormat,
-    int flags) throws TJException;
-
-  @Deprecated
-  private native void decompressToYUV(byte[] srcBuf, int size, byte[] dstBuf,
-    int flags) throws TJException;
-
-  private native void decompressToYUV(byte[] srcBuf, int size,
-    byte[][] dstPlanes, int[] dstOffsets, int desiredWidth, int[] dstStrides,
-    int desiredheight, int flags) throws TJException;
-
-  private native void decodeYUV(byte[][] srcPlanes, int[] srcOffsets,
-    int[] srcStrides, int subsamp, byte[] dstBuf, int x, int y, int width,
-    int pitch, int height, int pixelFormat, int flags) throws TJException;
-
-  private native void decodeYUV(byte[][] srcPlanes, int[] srcOffsets,
-    int[] srcStrides, int subsamp, int[] dstBuf, int x, int y, int width,
-    int stride, int height, int pixelFormat, int flags) throws TJException;
-
-  static {
-    TJLoader.load();
-  }
-
-  protected long handle = 0;
-  protected byte[] jpegBuf = null;
-  protected int jpegBufSize = 0;
-  protected YUVImage yuvImage = null;
-  protected int jpegWidth = 0;
-  protected int jpegHeight = 0;
-  protected int jpegSubsamp = -1;
-  protected int jpegColorspace = -1;
-  private ByteOrder byteOrder = null;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java
deleted file mode 100644
index d03a256..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C)2015 Viktor Szathmáry.  All Rights Reserved.
- * Copyright (C)2017-2018 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-import java.io.IOException;
-
-@SuppressWarnings("checkstyle:JavadocType")
-public class TJException extends IOException {
-
-  private static final long serialVersionUID = 1L;
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public TJException() {
-    super();
-  }
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public TJException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public TJException(String message) {
-    super(message);
-  }
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public TJException(String message, int code) {
-    super(message);
-    if (errorCode >= 0 && errorCode < TJ.NUMERR)
-      errorCode = code;
-  }
-
-  @SuppressWarnings("checkstyle:JavadocMethod")
-  public TJException(Throwable cause) {
-    super(cause);
-  }
-
-  /**
-   * Returns a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the
-   * last error.
-   *
-   * @return a code (one of {@link TJ TJ.ERR_*}) indicating the severity of the
-   * last error.
-   */
-  public int getErrorCode() {
-    return errorCode;
-  }
-
-  private int errorCode = TJ.ERR_FATAL;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-unix.java.in b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-unix.java.in
deleted file mode 100644
index 65884e8..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-unix.java.in
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C)2011-2013, 2016 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-final class TJLoader {
-  static void load() {
-    try {
-      System.loadLibrary("turbojpeg");
-    } catch (java.lang.UnsatisfiedLinkError e) {
-      String os = System.getProperty("os.name").toLowerCase();
-      if (os.indexOf("mac") >= 0) {
-        try {
-          System.load("@CMAKE_INSTALL_FULL_LIBDIR@/libturbojpeg.jnilib");
-        } catch (java.lang.UnsatisfiedLinkError e2) {
-          System.load("/usr/lib/libturbojpeg.jnilib");
-        }
-      } else {
-        try {
-          System.load("@CMAKE_INSTALL_FULL_LIBDIR@/libturbojpeg.so");
-        } catch (java.lang.UnsatisfiedLinkError e3) {
-          String libdir = "@CMAKE_INSTALL_FULL_LIBDIR@";
-          if (libdir.equals("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib64")) {
-            System.load("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib32/libturbojpeg.so");
-          } else if (libdir.equals("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib32")) {
-            System.load("@CMAKE_INSTALL_DEFAULT_PREFIX@/lib64/libturbojpeg.so");
-          } else {
-            throw e3;
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-win.java.in b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-win.java.in
deleted file mode 100644
index 8397780..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJLoader-win.java.in
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C)2011 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-final class TJLoader {
-  static void load() {
-    System.loadLibrary("@TURBOJPEG_DLL_NAME@");
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java
deleted file mode 100644
index ccf9179..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C)2011, 2018 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-/**
- * Fractional scaling factor
- */
-public class TJScalingFactor {
-
-  /**
-   * Create a TurboJPEG scaling factor instance.
-   *
-   * @param num numerator
-   * @param denom denominator
-   */
-  @SuppressWarnings("checkstyle:HiddenField")
-  public TJScalingFactor(int num, int denom) {
-    if (num < 1 || denom < 1)
-      throw new IllegalArgumentException("Numerator and denominator must be >= 1");
-    this.num = num;
-    this.denom = denom;
-  }
-
-  /**
-   * Returns numerator
-   *
-   * @return numerator
-   */
-  public int getNum() {
-    return num;
-  }
-
-  /**
-   * Returns denominator
-   *
-   * @return denominator
-   */
-  public int getDenom() {
-    return denom;
-  }
-
-  /**
-   * Returns the scaled value of <code>dimension</code>.  This function
-   * performs the integer equivalent of
-   * <code>ceil(dimension * scalingFactor)</code>.
-   *
-   * @param dimension width or height to multiply by this scaling factor
-   *
-   * @return the scaled value of <code>dimension</code>.
-   */
-  public int getScaled(int dimension) {
-    return (dimension * num + denom - 1) / denom;
-  }
-
-  /**
-   * Returns true or false, depending on whether this instance and
-   * <code>other</code> have the same numerator and denominator.
-   *
-   * @param other the scaling factor against which to compare this one
-   *
-   * @return true or false, depending on whether this instance and
-   * <code>other</code> have the same numerator and denominator.
-   */
-  public boolean equals(TJScalingFactor other) {
-    return this.num == other.num && this.denom == other.denom;
-  }
-
-  /**
-   * Returns true or false, depending on whether this instance is equal to
-   * 1/1.
-   *
-   * @return true or false, depending on whether this instance is equal to
-   * 1/1.
-   */
-  public boolean isOne() {
-    return num == 1 && denom == 1;
-  }
-
-  /**
-   * Numerator
-   */
-  private int num = 1;
-
-  /**
-   * Denominator
-   */
-  private int denom = 1;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java
deleted file mode 100644
index 41c4b45..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C)2011, 2013, 2018 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-import java.awt.*;
-
-/**
- * Lossless transform parameters
- */
-public class TJTransform extends Rectangle {
-
-  private static final long serialVersionUID = -127367705761430371L;
-
-  /**
-   * The number of lossless transform operations
-   */
-  public static final int NUMOP         = 8;
-  /**
-   * Do not transform the position of the image pixels.
-   */
-  public static final int OP_NONE       = 0;
-  /**
-   * Flip (mirror) image horizontally.  This transform is imperfect if there
-   * are any partial MCU blocks on the right edge.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_HFLIP      = 1;
-  /**
-   * Flip (mirror) image vertically.  This transform is imperfect if there are
-   * any partial MCU blocks on the bottom edge.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_VFLIP      = 2;
-  /**
-   * Transpose image (flip/mirror along upper left to lower right axis).  This
-   * transform is always perfect.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_TRANSPOSE  = 3;
-  /**
-   * Transverse transpose image (flip/mirror along upper right to lower left
-   * axis).  This transform is imperfect if there are any partial MCU blocks in
-   * the image.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_TRANSVERSE = 4;
-  /**
-   * Rotate image clockwise by 90 degrees.  This transform is imperfect if
-   * there are any partial MCU blocks on the bottom edge.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_ROT90      = 5;
-  /**
-   * Rotate image 180 degrees.  This transform is imperfect if there are any
-   * partial MCU blocks in the image.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_ROT180     = 6;
-  /**
-   * Rotate image counter-clockwise by 90 degrees.  This transform is imperfect
-   * if there are any partial MCU blocks on the right edge.
-   * @see #OPT_PERFECT
-   */
-  public static final int OP_ROT270     = 7;
-
-
-  /**
-   * This option will cause {@link TJTransformer#transform
-   * TJTransformer.transform()} to throw an exception if the transform is not
-   * perfect.  Lossless transforms operate on MCU blocks, whose size depends on
-   * the level of chrominance subsampling used.  If the image's width or height
-   * is not evenly divisible by the MCU block size (see {@link TJ#getMCUWidth}
-   * and {@link TJ#getMCUHeight}), then there will be partial MCU blocks on the
-   * right and/or bottom edges.   It is not possible to move these partial MCU
-   * blocks to the top or left of the image, so any transform that would
-   * require that is "imperfect."  If this option is not specified, then any
-   * partial MCU blocks that cannot be transformed will be left in place, which
-   * will create odd-looking strips on the right or bottom edge of the image.
-   */
-  public static final int OPT_PERFECT     = 1;
-  /**
-   * This option will discard any partial MCU blocks that cannot be
-   * transformed.
-   */
-  public static final int OPT_TRIM        = 2;
-  /**
-   * This option will enable lossless cropping.
-   */
-  public static final int OPT_CROP        = 4;
-  /**
-   * This option will discard the color data in the input image and produce
-   * a grayscale output image.
-   */
-  public static final int OPT_GRAY        = 8;
-  /**
-   * This option will prevent {@link TJTransformer#transform
-   * TJTransformer.transform()} from outputting a JPEG image for this
-   * particular transform.  This can be used in conjunction with a custom
-   * filter to capture the transformed DCT coefficients without transcoding
-   * them.
-   */
-  public static final int OPT_NOOUTPUT    = 16;
-  /**
-   * This option will enable progressive entropy coding in the output image
-   * generated by this particular transform.  Progressive entropy coding will
-   * generally improve compression relative to baseline entropy coding (the
-   * default), but it will reduce compression and decompression performance
-   * considerably.
-   */
-  public static final int OPT_PROGRESSIVE = 32;
-  /**
-   * This option will prevent {@link TJTransformer#transform
-   * TJTransformer.transform()} from copying any extra markers (including EXIF
-   * and ICC profile data) from the source image to the output image.
-   */
-  public static final int OPT_COPYNONE    = 64;
-
-
-  /**
-   * Create a new lossless transform instance.
-   */
-  public TJTransform() {
-  }
-
-  /**
-   * Create a new lossless transform instance with the given parameters.
-   *
-   * @param x the left boundary of the cropping region.  This must be evenly
-   * divisible by the MCU block width (see {@link TJ#getMCUWidth})
-   *
-   * @param y the upper boundary of the cropping region.  This must be evenly
-   * divisible by the MCU block height (see {@link TJ#getMCUHeight})
-   *
-   * @param w the width of the cropping region.  Setting this to 0 is the
-   * equivalent of setting it to (width of the source JPEG image -
-   * <code>x</code>).
-   *
-   * @param h the height of the cropping region.  Setting this to 0 is the
-   * equivalent of setting it to (height of the source JPEG image -
-   * <code>y</code>).
-   *
-   * @param op one of the transform operations (<code>OP_*</code>)
-   *
-   * @param options the bitwise OR of one or more of the transform options
-   * (<code>OPT_*</code>)
-   *
-   * @param cf an instance of an object that implements the {@link
-   * TJCustomFilter} interface, or null if no custom filter is needed
-   */
-  @SuppressWarnings("checkstyle:HiddenField")
-  public TJTransform(int x, int y, int w, int h, int op, int options,
-                     TJCustomFilter cf) {
-    super(x, y, w, h);
-    this.op = op;
-    this.options = options;
-    this.cf = cf;
-  }
-
-  /**
-   * Create a new lossless transform instance with the given parameters.
-   *
-   * @param r a <code>Rectangle</code> instance that specifies the cropping
-   * region.  See {@link
-   * #TJTransform(int, int, int, int, int, int, TJCustomFilter)} for more
-   * detail.
-   *
-   * @param op one of the transform operations (<code>OP_*</code>)
-   *
-   * @param options the bitwise OR of one or more of the transform options
-   * (<code>OPT_*</code>)
-   *
-   * @param cf an instance of an object that implements the {@link
-   * TJCustomFilter} interface, or null if no custom filter is needed
-   */
-  @SuppressWarnings("checkstyle:HiddenField")
-  public TJTransform(Rectangle r, int op, int options,
-                     TJCustomFilter cf) {
-    super(r);
-    this.op = op;
-    this.options = options;
-    this.cf = cf;
-  }
-
-  /**
-   * Transform operation (one of <code>OP_*</code>)
-   */
-  @SuppressWarnings("checkstyle:VisibilityModifier")
-  public int op = 0;
-
-  /**
-   * Transform options (bitwise OR of one or more of <code>OPT_*</code>)
-   */
-  @SuppressWarnings("checkstyle:VisibilityModifier")
-  public int options = 0;
-
-  /**
-   * Custom filter instance
-   */
-  @SuppressWarnings("checkstyle:VisibilityModifier")
-  public TJCustomFilter cf = null;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java
deleted file mode 100644
index d7a56f3..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C)2011, 2013-2015 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-/**
- * TurboJPEG lossless transformer
- */
-public class TJTransformer extends TJDecompressor {
-
-  /**
-   * Create a TurboJPEG lossless transformer instance.
-   */
-  public TJTransformer() throws TJException {
-    init();
-  }
-
-  /**
-   * Create a TurboJPEG lossless transformer instance and associate the JPEG
-   * image stored in <code>jpegImage</code> with the newly created instance.
-   *
-   * @param jpegImage JPEG image buffer (size of the JPEG image is assumed to
-   * be the length of the array.)  This buffer is not modified.
-   */
-  public TJTransformer(byte[] jpegImage) throws TJException {
-    init();
-    setSourceImage(jpegImage, jpegImage.length);
-  }
-
-  /**
-   * Create a TurboJPEG lossless transformer instance and associate the JPEG
-   * image of length <code>imageSize</code> bytes stored in
-   * <code>jpegImage</code> with the newly created instance.
-   *
-   * @param jpegImage JPEG image buffer.  This buffer is not modified.
-   *
-   * @param imageSize size of the JPEG image (in bytes)
-   */
-  public TJTransformer(byte[] jpegImage, int imageSize) throws TJException {
-    init();
-    setSourceImage(jpegImage, imageSize);
-  }
-
-  /**
-   * Losslessly transform the JPEG image associated with this transformer
-   * instance into one or more JPEG images stored in the given destination
-   * buffers.  Lossless transforms work by moving the raw coefficients from one
-   * JPEG image structure to another without altering the values of the
-   * coefficients.  While this is typically faster than decompressing the
-   * image, transforming it, and re-compressing it, lossless transforms are not
-   * free.  Each lossless transform requires reading and performing Huffman
-   * decoding on all of the coefficients in the source image, regardless of the
-   * size of the destination image.  Thus, this method provides a means of
-   * generating multiple transformed images from the same source or of applying
-   * multiple transformations simultaneously, in order to eliminate the need to
-   * read the source coefficients multiple times.
-   *
-   * @param dstBufs an array of image buffers.  <code>dstbufs[i]</code> will
-   * receive a JPEG image that has been transformed using the parameters in
-   * <code>transforms[i]</code>.  Use {@link TJ#bufSize} to determine the
-   * maximum size for each buffer based on the transformed or cropped width and
-   * height and the level of subsampling used in the source image.
-   *
-   * @param transforms an array of {@link TJTransform} instances, each of
-   * which specifies the transform parameters and/or cropping region for the
-   * corresponding transformed output image
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   */
-  public void transform(byte[][] dstBufs, TJTransform[] transforms,
-                        int flags) throws TJException {
-    if (jpegBuf == null)
-      throw new IllegalStateException("JPEG buffer not initialized");
-    transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms,
-                                 flags);
-  }
-
-  /**
-   * Losslessly transform the JPEG image associated with this transformer
-   * instance and return an array of {@link TJDecompressor} instances, each of
-   * which has a transformed JPEG image associated with it.
-   *
-   * @param transforms an array of {@link TJTransform} instances, each of
-   * which specifies the transform parameters and/or cropping region for the
-   * corresponding transformed output image
-   *
-   * @param flags the bitwise OR of one or more of
-   * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
-   *
-   * @return an array of {@link TJDecompressor} instances, each of
-   * which has a transformed JPEG image associated with it.
-   */
-  public TJDecompressor[] transform(TJTransform[] transforms, int flags)
-                                    throws TJException {
-    byte[][] dstBufs = new byte[transforms.length][];
-    if (jpegWidth < 1 || jpegHeight < 1)
-      throw new IllegalStateException("JPEG buffer not initialized");
-    for (int i = 0; i < transforms.length; i++) {
-      int w = jpegWidth, h = jpegHeight;
-      if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
-        if (transforms[i].width != 0) w = transforms[i].width;
-        if (transforms[i].height != 0) h = transforms[i].height;
-      }
-      dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)];
-    }
-    TJDecompressor[] tjd = new TJDecompressor[transforms.length];
-    transform(dstBufs, transforms, flags);
-    for (int i = 0; i < transforms.length; i++)
-      tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
-    return tjd;
-  }
-
-  /**
-   * Returns an array containing the sizes of the transformed JPEG images
-   * generated by the most recent transform operation.
-   *
-   * @return an array containing the sizes of the transformed JPEG images
-   * generated by the most recent transform operation.
-   */
-  public int[] getTransformedSizes() {
-    if (transformedSizes == null)
-      throw new IllegalStateException("No image has been transformed yet");
-    return transformedSizes;
-  }
-
-  private native void init() throws TJException;
-
-  private native int[] transform(byte[] srcBuf, int srcSize, byte[][] dstBufs,
-    TJTransform[] transforms, int flags) throws TJException;
-
-  static {
-    TJLoader.load();
-  }
-
-  private int[] transformedSizes = null;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java b/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java
deleted file mode 100644
index 4da9843..0000000
--- a/src/third_party/libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C)2014, 2017 D. R. Commander.  All Rights Reserved.
- * Copyright (C)2015 Viktor Szathmáry.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-package org.libjpegturbo.turbojpeg;
-
-/**
- * This class encapsulates a YUV planar image and the metadata
- * associated with it.  The TurboJPEG API allows both the JPEG compression and
- * decompression pipelines to be split into stages:  YUV encode, compress from
- * YUV, decompress to YUV, and YUV decode.  A <code>YUVImage</code> instance
- * serves as the destination image for YUV encode and decompress-to-YUV
- * operations and as the source image for compress-from-YUV and YUV decode
- * operations.
- * <p>
- * Technically, the JPEG format uses the YCbCr colorspace (which technically is
- * not a "colorspace" but rather a "color transform"), but per the convention
- * of the digital video community, the TurboJPEG API uses "YUV" to refer to an
- * image format consisting of Y, Cb, and Cr image planes.
- * <p>
- * Each plane is simply a 2D array of bytes, each byte representing the value
- * of one of the components (Y, Cb, or Cr) at a particular location in the
- * image.  The width and height of each plane are determined by the image
- * width, height, and level of chrominance subsampling.  The luminance plane
- * width is the image width padded to the nearest multiple of the horizontal
- * subsampling factor (2 in the case of 4:2:0 and 4:2:2, 4 in the case of
- * 4:1:1, 1 in the case of 4:4:4 or grayscale.)  Similarly, the luminance plane
- * height is the image height padded to the nearest multiple of the vertical
- * subsampling factor (2 in the case of 4:2:0 or 4:4:0, 1 in the case of 4:4:4
- * or grayscale.)  The chrominance plane width is equal to the luminance plane
- * width divided by the horizontal subsampling factor, and the chrominance
- * plane height is equal to the luminance plane height divided by the vertical
- * subsampling factor.
- * <p>
- * For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is
- * used, then the luminance plane would be 36 x 35 bytes, and each of the
- * chrominance planes would be 18 x 35 bytes.  If you specify a line padding of
- * 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and
- * each of the chrominance planes would be 20 x 35 bytes.
- */
-public class YUVImage {
-
-  private static final String NO_ASSOC_ERROR =
-    "No image data is associated with this instance";
-
-  /**
-   * Create a new <code>YUVImage</code> instance backed by separate image
-   * planes, and allocate memory for the image planes.
-   *
-   * @param width width (in pixels) of the YUV image
-   *
-   * @param strides an array of integers, each specifying the number of bytes
-   * per line in the corresponding plane of the YUV image.  Setting the stride
-   * for any plane to 0 is the same as setting it to the plane width (see
-   * {@link YUVImage above}.)  If <code>strides</code> is null, then the
-   * strides for all planes will be set to their respective plane widths.  When
-   * using this constructor, the stride for each plane must be equal to or
-   * greater than the plane width.
-   *
-   * @param height height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling to be used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public YUVImage(int width, int[] strides, int height, int subsamp) {
-    setBuf(null, null, width, strides, height, subsamp, true);
-  }
-
-  /**
-   * Create a new <code>YUVImage</code> instance backed by a unified image
-   * buffer, and allocate memory for the image buffer.
-   *
-   * @param width width (in pixels) of the YUV image
-   *
-   * @param pad Each line of each plane in the YUV image buffer will be padded
-   * to this number of bytes (must be a power of 2.)
-   *
-   * @param height height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling to be used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public YUVImage(int width, int pad, int height, int subsamp) {
-    setBuf(new byte[TJ.bufSizeYUV(width, pad, height, subsamp)], width, pad,
-           height, subsamp);
-  }
-
-  /**
-   * Create a new <code>YUVImage</code> instance from a set of existing image
-   * planes.
-   *
-   * @param planes an array of buffers representing the Y, U (Cb), and V (Cr)
-   * image planes (or just the Y plane, if the image is grayscale.)   These
-   * planes can be contiguous or non-contiguous in memory.  Plane
-   * <code>i</code> should be at least <code>offsets[i] +
-   * {@link TJ#planeSizeYUV TJ.planeSizeYUV}(i, width, strides[i], height, subsamp)</code>
-   * bytes in size.
-   *
-   * @param offsets If this <code>YUVImage</code> instance represents a
-   * subregion of a larger image, then <code>offsets[i]</code> specifies the
-   * offset (in bytes) of the subregion within plane <code>i</code> of the
-   * larger image.  Setting this to null is the same as setting the offsets for
-   * all planes to 0.
-   *
-   * @param width width (in pixels) of the new YUV image (or subregion)
-   *
-   * @param strides an array of integers, each specifying the number of bytes
-   * per line in the corresponding plane of the YUV image.  Setting the stride
-   * for any plane to 0 is the same as setting it to the plane width (see
-   * {@link YUVImage above}.)  If <code>strides</code> is null, then the
-   * strides for all planes will be set to their respective plane widths.  You
-   * can adjust the strides in order to add an arbitrary amount of line padding
-   * to each plane or to specify that this <code>YUVImage</code> instance is a
-   * subregion of a larger image (in which case, <code>strides[i]</code> should
-   * be set to the plane width of plane <code>i</code> in the larger image.)
-   *
-   * @param height height (in pixels) of the new YUV image (or subregion)
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public YUVImage(byte[][] planes, int[] offsets, int width, int[] strides,
-                  int height, int subsamp) {
-    setBuf(planes, offsets, width, strides, height, subsamp, false);
-  }
-
-  /**
-   * Create a new <code>YUVImage</code> instance from an existing unified image
-   * buffer.
-   *
-   * @param yuvImage image buffer that contains or will contain YUV planar
-   * image data.  Use {@link TJ#bufSizeYUV} to determine the minimum size for
-   * this buffer.  The Y, U (Cb), and V (Cr) image planes are stored
-   * sequentially in the buffer (see {@link YUVImage above} for a description
-   * of the image format.)
-   *
-   * @param width width (in pixels) of the YUV image
-   *
-   * @param pad the line padding used in the YUV image buffer.  For
-   * instance, if each line in each plane of the buffer is padded to the
-   * nearest multiple of 4 bytes, then <code>pad</code> should be set to 4.
-   *
-   * @param height height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public YUVImage(byte[] yuvImage, int width, int pad, int height,
-                  int subsamp) {
-    setBuf(yuvImage, width, pad, height, subsamp);
-  }
-
-  /**
-   * Assign a set of image planes to this <code>YUVImage</code> instance.
-   *
-   * @param planes an array of buffers representing the Y, U (Cb), and V (Cr)
-   * image planes (or just the Y plane, if the image is grayscale.)  These
-   * planes can be contiguous or non-contiguous in memory.  Plane
-   * <code>i</code> should be at least <code>offsets[i] +
-   * {@link TJ#planeSizeYUV TJ.planeSizeYUV}(i, width, strides[i], height, subsamp)</code>
-   * bytes in size.
-   *
-   * @param offsets If this <code>YUVImage</code> instance represents a
-   * subregion of a larger image, then <code>offsets[i]</code> specifies the
-   * offset (in bytes) of the subregion within plane <code>i</code> of the
-   * larger image.  Setting this to null is the same as setting the offsets for
-   * all planes to 0.
-   *
-   * @param width width (in pixels) of the YUV image (or subregion)
-   *
-   * @param strides an array of integers, each specifying the number of bytes
-   * per line in the corresponding plane of the YUV image.  Setting the stride
-   * for any plane to 0 is the same as setting it to the plane width (see
-   * {@link YUVImage above}.)  If <code>strides</code> is null, then the
-   * strides for all planes will be set to their respective plane widths.  You
-   * can adjust the strides in order to add an arbitrary amount of line padding
-   * to each plane or to specify that this <code>YUVImage</code> image is a
-   * subregion of a larger image (in which case, <code>strides[i]</code> should
-   * be set to the plane width of plane <code>i</code> in the larger image.)
-   *
-   * @param height height (in pixels) of the YUV image (or subregion)
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public void setBuf(byte[][] planes, int[] offsets, int width, int[] strides,
-                     int height, int subsamp) {
-    setBuf(planes, offsets, width, strides, height, subsamp, false);
-  }
-
-  private void setBuf(byte[][] planes, int[] offsets, int width, int[] strides,
-                     int height, int subsamp, boolean alloc) {
-    if ((planes == null && !alloc) || width < 1 || height < 1 || subsamp < 0 ||
-        subsamp >= TJ.NUMSAMP)
-      throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
-
-    int nc = (subsamp == TJ.SAMP_GRAY ? 1 : 3);
-    if ((planes != null && planes.length != nc) ||
-        (offsets != null && offsets.length != nc) ||
-        (strides != null && strides.length != nc))
-      throw new IllegalArgumentException("YUVImage::setBuf(): planes, offsets, or strides array is the wrong size");
-
-    if (planes == null)
-      planes = new byte[nc][];
-    if (offsets == null)
-      offsets = new int[nc];
-    if (strides == null)
-      strides = new int[nc];
-
-    for (int i = 0; i < nc; i++) {
-      int pw = TJ.planeWidth(i, width, subsamp);
-      int ph = TJ.planeHeight(i, height, subsamp);
-      int planeSize = TJ.planeSizeYUV(i, width, strides[i], height, subsamp);
-
-      if (strides[i] == 0)
-        strides[i] = pw;
-      if (alloc) {
-        if (strides[i] < pw)
-          throw new IllegalArgumentException("Stride must be >= plane width when allocating a new YUV image");
-        planes[i] = new byte[strides[i] * ph];
-      }
-      if (planes[i] == null || offsets[i] < 0)
-        throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
-      if (strides[i] < 0 && offsets[i] - planeSize + pw < 0)
-        throw new IllegalArgumentException("Stride for plane " + i +
-                                           " would cause memory to be accessed below plane boundary");
-      if (planes[i].length < offsets[i] + planeSize)
-        throw new IllegalArgumentException("Image plane " + i +
-                                           " is not large enough");
-    }
-
-    yuvPlanes = planes;
-    yuvOffsets = offsets;
-    yuvWidth = width;
-    yuvStrides = strides;
-    yuvHeight = height;
-    yuvSubsamp = subsamp;
-  }
-
-  /**
-   * Assign a unified image buffer to this <code>YUVImage</code> instance.
-   *
-   * @param yuvImage image buffer that contains or will contain YUV planar
-   * image data.  Use {@link TJ#bufSizeYUV} to determine the minimum size for
-   * this buffer.  The Y, U (Cb), and V (Cr) image planes are stored
-   * sequentially in the buffer (see {@link YUVImage above} for a description
-   * of the image format.)
-   *
-   * @param width width (in pixels) of the YUV image
-   *
-   * @param pad the line padding used in the YUV image buffer.  For
-   * instance, if each line in each plane of the buffer is padded to the
-   * nearest multiple of 4 bytes, then <code>pad</code> should be set to 4.
-   *
-   * @param height height (in pixels) of the YUV image
-   *
-   * @param subsamp the level of chrominance subsampling used in the YUV
-   * image (one of {@link TJ#SAMP_444 TJ.SAMP_*})
-   */
-  public void setBuf(byte[] yuvImage, int width, int pad, int height,
-                     int subsamp) {
-    if (yuvImage == null || width < 1 || pad < 1 || ((pad & (pad - 1)) != 0) ||
-        height < 1 || subsamp < 0 || subsamp >= TJ.NUMSAMP)
-      throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()");
-    if (yuvImage.length < TJ.bufSizeYUV(width, pad, height, subsamp))
-      throw new IllegalArgumentException("YUV image buffer is not large enough");
-
-    int nc = (subsamp == TJ.SAMP_GRAY ? 1 : 3);
-    byte[][] planes = new byte[nc][];
-    int[] strides = new int[nc];
-    int[] offsets = new int[nc];
-
-    planes[0] = yuvImage;
-    strides[0] = pad(TJ.planeWidth(0, width, subsamp), pad);
-    if (subsamp != TJ.SAMP_GRAY) {
-      strides[1] = strides[2] = pad(TJ.planeWidth(1, width, subsamp), pad);
-      planes[1] = planes[2] = yuvImage;
-      offsets[1] = offsets[0] +
-        strides[0] * TJ.planeHeight(0, height, subsamp);
-      offsets[2] = offsets[1] +
-        strides[1] * TJ.planeHeight(1, height, subsamp);
-    }
-
-    yuvPad = pad;
-    setBuf(planes, offsets, width, strides, height, subsamp);
-  }
-
-  /**
-   * Returns the width of the YUV image (or subregion.)
-   *
-   * @return the width of the YUV image (or subregion)
-   */
-  public int getWidth() {
-    if (yuvWidth < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvWidth;
-  }
-
-  /**
-   * Returns the height of the YUV image (or subregion.)
-   *
-   * @return the height of the YUV image (or subregion)
-   */
-  public int getHeight() {
-    if (yuvHeight < 1)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvHeight;
-  }
-
-  /**
-   * Returns the line padding used in the YUV image buffer (if this image is
-   * stored in a unified buffer rather than separate image planes.)
-   *
-   * @return the line padding used in the YUV image buffer
-   */
-  public int getPad() {
-    if (yuvPlanes == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    if (yuvPad < 1 || ((yuvPad & (yuvPad - 1)) != 0))
-      throw new IllegalStateException("Image is not stored in a unified buffer");
-    return yuvPad;
-  }
-
-  /**
-   * Returns the number of bytes per line of each plane in the YUV image.
-   *
-   * @return the number of bytes per line of each plane in the YUV image
-   */
-  public int[] getStrides() {
-    if (yuvStrides == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvStrides;
-  }
-
-  /**
-   * Returns the offsets (in bytes) of each plane within the planes of a larger
-   * YUV image.
-   *
-   * @return the offsets (in bytes) of each plane within the planes of a larger
-   * YUV image
-   */
-  public int[] getOffsets() {
-    if (yuvOffsets == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvOffsets;
-  }
-
-  /**
-   * Returns the level of chrominance subsampling used in the YUV image.  See
-   * {@link TJ#SAMP_444 TJ.SAMP_*}.
-   *
-   * @return the level of chrominance subsampling used in the YUV image
-   */
-  public int getSubsamp() {
-    if (yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvSubsamp;
-  }
-
-  /**
-   * Returns the YUV image planes.  If the image is stored in a unified buffer,
-   * then all image planes will point to that buffer.
-   *
-   * @return the YUV image planes
-   */
-  public byte[][] getPlanes() {
-    if (yuvPlanes == null)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    return yuvPlanes;
-  }
-
-  /**
-   * Returns the YUV image buffer (if this image is stored in a unified
-   * buffer rather than separate image planes.)
-   *
-   * @return the YUV image buffer
-   */
-  public byte[] getBuf() {
-    if (yuvPlanes == null || yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    int nc = (yuvSubsamp == TJ.SAMP_GRAY ? 1 : 3);
-    for (int i = 1; i < nc; i++) {
-      if (yuvPlanes[i] != yuvPlanes[0])
-        throw new IllegalStateException("Image is not stored in a unified buffer");
-    }
-    return yuvPlanes[0];
-  }
-
-  /**
-   * Returns the size (in bytes) of the YUV image buffer (if this image is
-   * stored in a unified buffer rather than separate image planes.)
-   *
-   * @return the size (in bytes) of the YUV image buffer
-   */
-  public int getSize() {
-    if (yuvPlanes == null || yuvSubsamp < 0 || yuvSubsamp >= TJ.NUMSAMP)
-      throw new IllegalStateException(NO_ASSOC_ERROR);
-    int nc = (yuvSubsamp == TJ.SAMP_GRAY ? 1 : 3);
-    if (yuvPad < 1)
-      throw new IllegalStateException("Image is not stored in a unified buffer");
-    for (int i = 1; i < nc; i++) {
-      if (yuvPlanes[i] != yuvPlanes[0])
-        throw new IllegalStateException("Image is not stored in a unified buffer");
-    }
-    return TJ.bufSizeYUV(yuvWidth, yuvPad, yuvHeight, yuvSubsamp);
-  }
-
-  private static int pad(int v, int p) {
-    return (v + p - 1) & (~(p - 1));
-  }
-
-  protected long handle = 0;
-  protected byte[][] yuvPlanes = null;
-  protected int[] yuvOffsets = null;
-  protected int[] yuvStrides = null;
-  protected int yuvPad = 0;
-  protected int yuvWidth = 0;
-  protected int yuvHeight = 0;
-  protected int yuvSubsamp = -1;
-}
diff --git a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJ.h b/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJ.h
deleted file mode 100644
index 84ee871..0000000
--- a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJ.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_libjpegturbo_turbojpeg_TJ */
-
-#ifndef _Included_org_libjpegturbo_turbojpeg_TJ
-#define _Included_org_libjpegturbo_turbojpeg_TJ
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef org_libjpegturbo_turbojpeg_TJ_NUMSAMP
-#define org_libjpegturbo_turbojpeg_TJ_NUMSAMP 6L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_444
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_444 0L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_422
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_422 1L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_420
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_420 2L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY 3L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_440
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_440 4L
-#undef org_libjpegturbo_turbojpeg_TJ_SAMP_411
-#define org_libjpegturbo_turbojpeg_TJ_SAMP_411 5L
-#undef org_libjpegturbo_turbojpeg_TJ_NUMPF
-#define org_libjpegturbo_turbojpeg_TJ_NUMPF 12L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_RGB
-#define org_libjpegturbo_turbojpeg_TJ_PF_RGB 0L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_BGR
-#define org_libjpegturbo_turbojpeg_TJ_PF_BGR 1L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_RGBX
-#define org_libjpegturbo_turbojpeg_TJ_PF_RGBX 2L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_BGRX
-#define org_libjpegturbo_turbojpeg_TJ_PF_BGRX 3L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_XBGR
-#define org_libjpegturbo_turbojpeg_TJ_PF_XBGR 4L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_XRGB
-#define org_libjpegturbo_turbojpeg_TJ_PF_XRGB 5L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_GRAY
-#define org_libjpegturbo_turbojpeg_TJ_PF_GRAY 6L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_RGBA
-#define org_libjpegturbo_turbojpeg_TJ_PF_RGBA 7L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_BGRA
-#define org_libjpegturbo_turbojpeg_TJ_PF_BGRA 8L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_ABGR
-#define org_libjpegturbo_turbojpeg_TJ_PF_ABGR 9L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_ARGB
-#define org_libjpegturbo_turbojpeg_TJ_PF_ARGB 10L
-#undef org_libjpegturbo_turbojpeg_TJ_PF_CMYK
-#define org_libjpegturbo_turbojpeg_TJ_PF_CMYK 11L
-#undef org_libjpegturbo_turbojpeg_TJ_NUMCS
-#define org_libjpegturbo_turbojpeg_TJ_NUMCS 5L
-#undef org_libjpegturbo_turbojpeg_TJ_CS_RGB
-#define org_libjpegturbo_turbojpeg_TJ_CS_RGB 0L
-#undef org_libjpegturbo_turbojpeg_TJ_CS_YCbCr
-#define org_libjpegturbo_turbojpeg_TJ_CS_YCbCr 1L
-#undef org_libjpegturbo_turbojpeg_TJ_CS_GRAY
-#define org_libjpegturbo_turbojpeg_TJ_CS_GRAY 2L
-#undef org_libjpegturbo_turbojpeg_TJ_CS_CMYK
-#define org_libjpegturbo_turbojpeg_TJ_CS_CMYK 3L
-#undef org_libjpegturbo_turbojpeg_TJ_CS_YCCK
-#define org_libjpegturbo_turbojpeg_TJ_CS_YCCK 4L
-#undef org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP
-#define org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP 2L
-#undef org_libjpegturbo_turbojpeg_TJ_FLAG_FASTUPSAMPLE
-#define org_libjpegturbo_turbojpeg_TJ_FLAG_FASTUPSAMPLE 256L
-#undef org_libjpegturbo_turbojpeg_TJ_FLAG_FASTDCT
-#define org_libjpegturbo_turbojpeg_TJ_FLAG_FASTDCT 2048L
-#undef org_libjpegturbo_turbojpeg_TJ_FLAG_ACCURATEDCT
-#define org_libjpegturbo_turbojpeg_TJ_FLAG_ACCURATEDCT 4096L
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    bufSize
- * Signature: (III)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
-  (JNIEnv *, jclass, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    bufSizeYUV
- * Signature: (IIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII
-  (JNIEnv *, jclass, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    bufSizeYUV
- * Signature: (III)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III
-  (JNIEnv *, jclass, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    planeSizeYUV
- * Signature: (IIIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII
-  (JNIEnv *, jclass, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    planeWidth
- * Signature: (III)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III
-  (JNIEnv *, jclass, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    planeHeight
- * Signature: (III)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III
-  (JNIEnv *, jclass, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJ
- * Method:    getScalingFactors
- * Signature: ()[Lorg/libjpegturbo/turbojpeg/TJScalingFactor;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJCompressor.h b/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJCompressor.h
deleted file mode 100644
index e76bd0e..0000000
--- a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJCompressor.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_libjpegturbo_turbojpeg_TJCompressor */
-
-#ifndef _Included_org_libjpegturbo_turbojpeg_TJCompressor
-#define _Included_org_libjpegturbo_turbojpeg_TJCompressor
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    destroy
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    compress
- * Signature: ([BIIII[BIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    compress
- * Signature: ([BIIIIII[BIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    compress
- * Signature: ([IIIII[BIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
-  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    compress
- * Signature: ([IIIIIII[BIII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
-  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    compressFromYUV
- * Signature: ([[B[II[III[BII)I
- */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII
-  (JNIEnv *, jobject, jobjectArray, jintArray, jint, jintArray, jint, jint, jbyteArray, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    encodeYUV
- * Signature: ([BIIII[BII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    encodeYUV
- * Signature: ([BIIIIII[[B[I[III)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3_3B_3I_3III
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jint, jint, jobjectArray, jintArray, jintArray, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    encodeYUV
- * Signature: ([IIIII[BII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
-  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jbyteArray, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJCompressor
- * Method:    encodeYUV
- * Signature: ([IIIIIII[[B[I[III)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3_3B_3I_3III
-  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jint, jint, jobjectArray, jintArray, jintArray, jint, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJDecompressor.h b/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJDecompressor.h
deleted file mode 100644
index 2d58e73..0000000
--- a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJDecompressor.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_libjpegturbo_turbojpeg_TJDecompressor */
-
-#ifndef _Included_org_libjpegturbo_turbojpeg_TJDecompressor
-#define _Included_org_libjpegturbo_turbojpeg_TJDecompressor
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    destroy
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompressHeader
- * Signature: ([BI)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
-  (JNIEnv *, jobject, jbyteArray, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompress
- * Signature: ([BI[BIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
-  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompress
- * Signature: ([BI[BIIIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
-  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompress
- * Signature: ([BI[IIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
-  (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompress
- * Signature: ([BI[IIIIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
-  (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompressToYUV
- * Signature: ([BI[BI)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
-  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decompressToYUV
- * Signature: ([BI[[B[II[III)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III
-  (JNIEnv *, jobject, jbyteArray, jint, jobjectArray, jintArray, jint, jintArray, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decodeYUV
- * Signature: ([[B[I[II[BIIIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3BIIIIIII
-  (JNIEnv *, jobject, jobjectArray, jintArray, jintArray, jint, jbyteArray, jint, jint, jint, jint, jint, jint, jint);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
- * Method:    decodeYUV
- * Signature: ([[B[I[II[IIIIIIII)V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3IIIIIIII
-  (JNIEnv *, jobject, jobjectArray, jintArray, jintArray, jint, jintArray, jint, jint, jint, jint, jint, jint, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJTransformer.h b/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJTransformer.h
deleted file mode 100644
index a9dad4d..0000000
--- a/src/third_party/libjpeg-turbo/java/org_libjpegturbo_turbojpeg_TJTransformer.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_libjpegturbo_turbojpeg_TJTransformer */
-
-#ifndef _Included_org_libjpegturbo_turbojpeg_TJTransformer
-#define _Included_org_libjpegturbo_turbojpeg_TJTransformer
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJTransformer
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_libjpegturbo_turbojpeg_TJTransformer
- * Method:    transform
- * Signature: ([BI[[B[Lorg/libjpegturbo/turbojpeg/TJTransform;I)[I
- */
-JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
-  (JNIEnv *, jobject, jbyteArray, jint, jobjectArray, jobjectArray, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/third_party/libjpeg-turbo/jcarith.c b/src/third_party/libjpeg-turbo/jcarith.c
index c55c0ea..b6d093f 100644
--- a/src/third_party/libjpeg-turbo/jcarith.c
+++ b/src/third_party/libjpeg-turbo/jcarith.c
@@ -9,11 +9,14 @@
  * file.
  *
  * This file contains portable arithmetic entropy encoding routines for JPEG
- * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
+ * (implementing Recommendation ITU-T T.81 | ISO/IEC 10918-1).
  *
  * Both sequential and progressive modes are supported in this single module.
  *
  * Suspension is not currently supported in this module.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  */
 
 #define JPEG_INTERNALS
diff --git a/src/third_party/libjpeg-turbo/jccolext.c b/src/third_party/libjpeg-turbo/jccolext.c
index 19c955c..303b322 100644
--- a/src/third_party/libjpeg-turbo/jccolext.c
+++ b/src/third_party/libjpeg-turbo/jccolext.c
@@ -48,9 +48,9 @@
     outptr2 = output_buf[2][output_row];
     output_row++;
     for (col = 0; col < num_cols; col++) {
-      r = GETJSAMPLE(inptr[RGB_RED]);
-      g = GETJSAMPLE(inptr[RGB_GREEN]);
-      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      r = inptr[RGB_RED];
+      g = inptr[RGB_GREEN];
+      b = inptr[RGB_BLUE];
       inptr += RGB_PIXELSIZE;
       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
        * must be too; we do not need an explicit range-limiting operation.
@@ -100,9 +100,9 @@
     outptr = output_buf[0][output_row];
     output_row++;
     for (col = 0; col < num_cols; col++) {
-      r = GETJSAMPLE(inptr[RGB_RED]);
-      g = GETJSAMPLE(inptr[RGB_GREEN]);
-      b = GETJSAMPLE(inptr[RGB_BLUE]);
+      r = inptr[RGB_RED];
+      g = inptr[RGB_GREEN];
+      b = inptr[RGB_BLUE];
       inptr += RGB_PIXELSIZE;
       /* Y */
       outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
@@ -135,9 +135,9 @@
     outptr2 = output_buf[2][output_row];
     output_row++;
     for (col = 0; col < num_cols; col++) {
-      outptr0[col] = GETJSAMPLE(inptr[RGB_RED]);
-      outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]);
-      outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]);
+      outptr0[col] = inptr[RGB_RED];
+      outptr1[col] = inptr[RGB_GREEN];
+      outptr2[col] = inptr[RGB_BLUE];
       inptr += RGB_PIXELSIZE;
     }
   }
diff --git a/src/third_party/libjpeg-turbo/jccolor.c b/src/third_party/libjpeg-turbo/jccolor.c
index 036f601..bdc563c 100644
--- a/src/third_party/libjpeg-turbo/jccolor.c
+++ b/src/third_party/libjpeg-turbo/jccolor.c
@@ -392,11 +392,11 @@
     outptr3 = output_buf[3][output_row];
     output_row++;
     for (col = 0; col < num_cols; col++) {
-      r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
-      g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
-      b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
+      r = MAXJSAMPLE - inptr[0];
+      g = MAXJSAMPLE - inptr[1];
+      b = MAXJSAMPLE - inptr[2];
       /* K passes through as-is */
-      outptr3[col] = inptr[3];  /* don't need GETJSAMPLE here */
+      outptr3[col] = inptr[3];
       inptr += 4;
       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
        * must be too; we do not need an explicit range-limiting operation.
@@ -438,7 +438,7 @@
     outptr = output_buf[0][output_row];
     output_row++;
     for (col = 0; col < num_cols; col++) {
-      outptr[col] = inptr[0];   /* don't need GETJSAMPLE() here */
+      outptr[col] = inptr[0];
       inptr += instride;
     }
   }
@@ -497,7 +497,7 @@
         inptr = *input_buf;
         outptr = output_buf[ci][output_row];
         for (col = 0; col < num_cols; col++) {
-          outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
+          outptr[col] = inptr[ci];
           inptr += nc;
         }
       }
diff --git a/src/third_party/libjpeg-turbo/jcdctmgr.c b/src/third_party/libjpeg-turbo/jcdctmgr.c
index c04058e..7dae17a 100644
--- a/src/third_party/libjpeg-turbo/jcdctmgr.c
+++ b/src/third_party/libjpeg-turbo/jcdctmgr.c
@@ -381,19 +381,19 @@
     elemptr = sample_data[elemr] + start_col;
 
 #if DCTSIZE == 8                /* unroll the inner loop */
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
-    *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
+    *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
 #else
     {
       register int elemc;
       for (elemc = DCTSIZE; elemc > 0; elemc--)
-        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+        *workspaceptr++ = (*elemptr++) - CENTERJSAMPLE;
     }
 #endif
   }
@@ -533,20 +533,19 @@
   for (elemr = 0; elemr < DCTSIZE; elemr++) {
     elemptr = sample_data[elemr] + start_col;
 #if DCTSIZE == 8                /* unroll the inner loop */
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
-    *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
+    *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
 #else
     {
       register int elemc;
       for (elemc = DCTSIZE; elemc > 0; elemc--)
-        *workspaceptr++ = (FAST_FLOAT)
-                          (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+        *workspaceptr++ = (FAST_FLOAT)((*elemptr++) - CENTERJSAMPLE);
     }
 #endif
   }
diff --git a/src/third_party/libjpeg-turbo/jchuff.c b/src/third_party/libjpeg-turbo/jchuff.c
index dc5a1f3..8ff817b 100644
--- a/src/third_party/libjpeg-turbo/jchuff.c
+++ b/src/third_party/libjpeg-turbo/jchuff.c
@@ -4,8 +4,10 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009-2011, 2014-2016, D. R. Commander.
+ * Copyright (C) 2009-2011, 2014-2016, 2018-2021, D. R. Commander.
  * Copyright (C) 2015, Matthieu Darbois.
+ * Copyright (C) 2018, Matthias Räncker.
+ * Copyright (C) 2020, Arm Limited.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -16,6 +18,9 @@
  * back up to the start of the current MCU.  To do this, we copy state
  * variables into local working storage, and update them back to the
  * permanent JPEG objects only upon successful completion of an MCU.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  */
 
 #define JPEG_INTERNALS
@@ -31,23 +36,28 @@
  * memory footprint by 64k, which is important for some mobile applications
  * that create many isolated instances of libjpeg-turbo (web browsers, for
  * instance.)  This may improve performance on some mobile platforms as well.
- * This feature is enabled by default only on ARM processors, because some x86
+ * This feature is enabled by default only on Arm processors, because some x86
  * chips have a slow implementation of bsr, and the use of clz/bsr cannot be
  * shown to have a significant performance impact even on the x86 chips that
- * have a fast implementation of it.  When building for ARMv6, you can
+ * have a fast implementation of it.  When building for Armv6, you can
  * explicitly disable the use of clz/bsr by adding -mthumb to the compiler
  * flags (this defines __thumb__).
  */
 
 /* NOTE: Both GCC and Clang define __GNUC__ */
-#if defined __GNUC__ && (defined __arm__ || defined __aarch64__)
-#if !defined __thumb__ || defined __thumb2__
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
+    defined(_M_ARM) || defined(_M_ARM64)
+#if !defined(__thumb__) || defined(__thumb2__)
 #define USE_CLZ_INTRINSIC
 #endif
 #endif
 
 #ifdef USE_CLZ_INTRINSIC
+#if defined(_MSC_VER) && !defined(__clang__)
+#define JPEG_NBITS_NONZERO(x)  (32 - _CountLeadingZeros(x))
+#else
 #define JPEG_NBITS_NONZERO(x)  (32 - __builtin_clz(x))
+#endif
 #define JPEG_NBITS(x)          (x ? JPEG_NBITS_NONZERO(x) : 0)
 #else
 #include "jpeg_nbits_table.h"
@@ -62,32 +72,43 @@
  * but must not be updated permanently until we complete the MCU.
  */
 
+#if defined(__x86_64__) && defined(__ILP32__)
+typedef unsigned long long bit_buf_type;
+#else
+typedef size_t bit_buf_type;
+#endif
+
+/* NOTE: The more optimal Huffman encoding algorithm is only used by the
+ * intrinsics implementation of the Arm Neon SIMD extensions, which is why we
+ * retain the old Huffman encoder behavior when using the GAS implementation.
+ */
+#if defined(WITH_SIMD) && !(defined(__arm__) || defined(__aarch64__) || \
+                            defined(_M_ARM) || defined(_M_ARM64))
+typedef unsigned long long simd_bit_buf_type;
+#else
+typedef bit_buf_type simd_bit_buf_type;
+#endif
+
+#if (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 8) || defined(_WIN64) || \
+    (defined(__x86_64__) && defined(__ILP32__))
+#define BIT_BUF_SIZE  64
+#elif (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 4) || defined(_WIN32)
+#define BIT_BUF_SIZE  32
+#else
+#error Cannot determine word size
+#endif
+#define SIMD_BIT_BUF_SIZE  (sizeof(simd_bit_buf_type) * 8)
+
 typedef struct {
-  size_t put_buffer;                    /* current bit-accumulation buffer */
-  int put_bits;                         /* # of bits now in it */
+  union {
+    bit_buf_type c;
+    simd_bit_buf_type simd;
+  } put_buffer;                         /* current bit accumulation buffer */
+  int free_bits;                        /* # of bits available in it */
+                                        /* (Neon GAS: # of bits now in it) */
   int last_dc_val[MAX_COMPS_IN_SCAN];   /* last DC coef for each component */
 } savable_state;
 
-/* This macro is to work around compilers with missing or broken
- * structure assignment.  You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
-#ifndef NO_STRUCT_ASSIGN
-#define ASSIGN_STATE(dest, src)  ((dest) = (src))
-#else
-#if MAX_COMPS_IN_SCAN == 4
-#define ASSIGN_STATE(dest, src) \
-  ((dest).put_buffer = (src).put_buffer, \
-   (dest).put_bits = (src).put_bits, \
-   (dest).last_dc_val[0] = (src).last_dc_val[0], \
-   (dest).last_dc_val[1] = (src).last_dc_val[1], \
-   (dest).last_dc_val[2] = (src).last_dc_val[2], \
-   (dest).last_dc_val[3] = (src).last_dc_val[3])
-#endif
-#endif
-
-
 typedef struct {
   struct jpeg_entropy_encoder pub; /* public fields */
 
@@ -120,6 +141,7 @@
   size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
   savable_state cur;            /* Current bit buffer & DC state */
   j_compress_ptr cinfo;         /* dump_buffer needs access to this */
+  int simd;
 } working_state;
 
 
@@ -198,8 +220,17 @@
   }
 
   /* Initialize bit buffer to empty */
-  entropy->saved.put_buffer = 0;
-  entropy->saved.put_bits = 0;
+  if (entropy->simd) {
+    entropy->saved.put_buffer.simd = 0;
+#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
+    entropy->saved.free_bits = 0;
+#else
+    entropy->saved.free_bits = SIMD_BIT_BUF_SIZE;
+#endif
+  } else {
+    entropy->saved.put_buffer.c = 0;
+    entropy->saved.free_bits = BIT_BUF_SIZE;
+  }
 
   /* Initialize restart stuff */
   entropy->restarts_to_go = cinfo->restart_interval;
@@ -284,6 +315,7 @@
    * this lets us detect duplicate VAL entries here, and later
    * allows emit_bits to detect any attempt to emit such symbols.
    */
+  MEMZERO(dtbl->ehufco, sizeof(dtbl->ehufco));
   MEMZERO(dtbl->ehufsi, sizeof(dtbl->ehufsi));
 
   /* This is also a convenient place to check for out-of-range
@@ -331,90 +363,94 @@
 
 /* Outputting bits to the file */
 
-/* These macros perform the same task as the emit_bits() function in the
- * original libjpeg code.  In addition to reducing overhead by explicitly
- * inlining the code, additional performance is achieved by taking into
- * account the size of the bit buffer and waiting until it is almost full
- * before emptying it.  This mostly benefits 64-bit platforms, since 6
- * bytes can be stored in a 64-bit bit buffer before it has to be emptied.
+/* Output byte b and, speculatively, an additional 0 byte.  0xFF must be
+ * encoded as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the
+ * byte is 0xFF.  Otherwise, the output buffer pointer is advanced by 1, and
+ * the speculative 0 byte will be overwritten by the next byte.
  */
-
-#define EMIT_BYTE() { \
-  JOCTET c; \
-  put_bits -= 8; \
-  c = (JOCTET)GETJOCTET(put_buffer >> put_bits); \
-  *buffer++ = c; \
-  if (c == 0xFF)  /* need to stuff a zero byte? */ \
-    *buffer++ = 0; \
+#define EMIT_BYTE(b) { \
+  buffer[0] = (JOCTET)(b); \
+  buffer[1] = 0; \
+  buffer -= -2 + ((JOCTET)(b) < 0xFF); \
 }
 
-#define PUT_BITS(code, size) { \
-  put_bits += size; \
-  put_buffer = (put_buffer << size) | code; \
-}
+/* Output the entire bit buffer.  If there are no 0xFF bytes in it, then write
+ * directly to the output buffer.  Otherwise, use the EMIT_BYTE() macro to
+ * encode 0xFF as 0xFF 0x00.
+ */
+#if BIT_BUF_SIZE == 64
 
-#define CHECKBUF15() { \
-  if (put_bits > 15) { \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
+#define FLUSH() { \
+  if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
+    EMIT_BYTE(put_buffer >> 56) \
+    EMIT_BYTE(put_buffer >> 48) \
+    EMIT_BYTE(put_buffer >> 40) \
+    EMIT_BYTE(put_buffer >> 32) \
+    EMIT_BYTE(put_buffer >> 24) \
+    EMIT_BYTE(put_buffer >> 16) \
+    EMIT_BYTE(put_buffer >>  8) \
+    EMIT_BYTE(put_buffer      ) \
+  } else { \
+    buffer[0] = (JOCTET)(put_buffer >> 56); \
+    buffer[1] = (JOCTET)(put_buffer >> 48); \
+    buffer[2] = (JOCTET)(put_buffer >> 40); \
+    buffer[3] = (JOCTET)(put_buffer >> 32); \
+    buffer[4] = (JOCTET)(put_buffer >> 24); \
+    buffer[5] = (JOCTET)(put_buffer >> 16); \
+    buffer[6] = (JOCTET)(put_buffer >> 8); \
+    buffer[7] = (JOCTET)(put_buffer); \
+    buffer += 8; \
   } \
 }
 
-#define CHECKBUF31() { \
-  if (put_bits > 31) { \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-  } \
-}
-
-#define CHECKBUF47() { \
-  if (put_bits > 47) { \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-    EMIT_BYTE() \
-  } \
-}
-
-#if !defined(_WIN32) && !defined(SIZEOF_SIZE_T)
-#error Cannot determine word size
-#endif
-
-#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
-
-#define EMIT_BITS(code, size) { \
-  CHECKBUF47() \
-  PUT_BITS(code, size) \
-}
-
-#define EMIT_CODE(code, size) { \
-  temp2 &= (((JLONG)1) << nbits) - 1; \
-  CHECKBUF31() \
-  PUT_BITS(code, size) \
-  PUT_BITS(temp2, nbits) \
-}
-
 #else
 
-#define EMIT_BITS(code, size) { \
-  PUT_BITS(code, size) \
-  CHECKBUF15() \
-}
-
-#define EMIT_CODE(code, size) { \
-  temp2 &= (((JLONG)1) << nbits) - 1; \
-  PUT_BITS(code, size) \
-  CHECKBUF15() \
-  PUT_BITS(temp2, nbits) \
-  CHECKBUF15() \
+#define FLUSH() { \
+  if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
+    EMIT_BYTE(put_buffer >> 24) \
+    EMIT_BYTE(put_buffer >> 16) \
+    EMIT_BYTE(put_buffer >>  8) \
+    EMIT_BYTE(put_buffer      ) \
+  } else { \
+    buffer[0] = (JOCTET)(put_buffer >> 24); \
+    buffer[1] = (JOCTET)(put_buffer >> 16); \
+    buffer[2] = (JOCTET)(put_buffer >> 8); \
+    buffer[3] = (JOCTET)(put_buffer); \
+    buffer += 4; \
+  } \
 }
 
 #endif
 
+/* Fill the bit buffer to capacity with the leading bits from code, then output
+ * the bit buffer and put the remaining bits from code into the bit buffer.
+ */
+#define PUT_AND_FLUSH(code, size) { \
+  put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
+  FLUSH() \
+  free_bits += BIT_BUF_SIZE; \
+  put_buffer = code; \
+}
+
+/* Insert code into the bit buffer and output the bit buffer if needed.
+ * NOTE: We can't flush with free_bits == 0, since the left shift in
+ * PUT_AND_FLUSH() would have undefined behavior.
+ */
+#define PUT_BITS(code, size) { \
+  free_bits -= size; \
+  if (free_bits < 0) \
+    PUT_AND_FLUSH(code, size) \
+  else \
+    put_buffer = (put_buffer << size) | code; \
+}
+
+#define PUT_CODE(code, size) { \
+  temp &= (((JLONG)1) << nbits) - 1; \
+  temp |= code << nbits; \
+  nbits += size; \
+  PUT_BITS(temp, nbits) \
+}
+
 
 /* Although it is exceedingly rare, it is possible for a Huffman-encoded
  * coefficient block to be larger than the 128-byte unencoded block.  For each
@@ -425,7 +461,7 @@
  * scanning order-- 1, 8, 16, etc.), then this will produce an encoded block
  * larger than 200 bytes.
  */
-#define BUFSIZE  (DCTSIZE2 * 4)
+#define BUFSIZE  (DCTSIZE2 * 8)
 
 #define LOAD_BUFFER() { \
   if (state->free_in_buffer < BUFSIZE) { \
@@ -437,6 +473,7 @@
 
 #define STORE_BUFFER() { \
   if (localbuf) { \
+    size_t bytes, bytestocopy; \
     bytes = buffer - _buffer; \
     buffer = _buffer; \
     while (bytes > 0) { \
@@ -459,20 +496,46 @@
 LOCAL(boolean)
 flush_bits(working_state *state)
 {
-  JOCTET _buffer[BUFSIZE], *buffer;
-  size_t put_buffer;  int put_bits;
-  size_t bytes, bytestocopy;  int localbuf = 0;
+  JOCTET _buffer[BUFSIZE], *buffer, temp;
+  simd_bit_buf_type put_buffer;  int put_bits;
+  int localbuf = 0;
 
-  put_buffer = state->cur.put_buffer;
-  put_bits = state->cur.put_bits;
+  if (state->simd) {
+#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
+    put_bits = state->cur.free_bits;
+#else
+    put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits;
+#endif
+    put_buffer = state->cur.put_buffer.simd;
+  } else {
+    put_bits = BIT_BUF_SIZE - state->cur.free_bits;
+    put_buffer = state->cur.put_buffer.c;
+  }
+
   LOAD_BUFFER()
 
-  /* fill any partial byte with ones */
-  PUT_BITS(0x7F, 7)
-  while (put_bits >= 8) EMIT_BYTE()
+  while (put_bits >= 8) {
+    put_bits -= 8;
+    temp = (JOCTET)(put_buffer >> put_bits);
+    EMIT_BYTE(temp)
+  }
+  if (put_bits) {
+    /* fill partial byte with ones */
+    temp = (JOCTET)((put_buffer << (8 - put_bits)) | (0xFF >> put_bits));
+    EMIT_BYTE(temp)
+  }
 
-  state->cur.put_buffer = 0;    /* and reset bit-buffer to empty */
-  state->cur.put_bits = 0;
+  if (state->simd) {                    /* and reset bit buffer to empty */
+    state->cur.put_buffer.simd = 0;
+#if defined(__aarch64__) && !defined(NEON_INTRINSICS)
+    state->cur.free_bits = 0;
+#else
+    state->cur.free_bits = SIMD_BIT_BUF_SIZE;
+#endif
+  } else {
+    state->cur.put_buffer.c = 0;
+    state->cur.free_bits = BIT_BUF_SIZE;
+  }
   STORE_BUFFER()
 
   return TRUE;
@@ -486,7 +549,7 @@
                       c_derived_tbl *dctbl, c_derived_tbl *actbl)
 {
   JOCTET _buffer[BUFSIZE], *buffer;
-  size_t bytes, bytestocopy;  int localbuf = 0;
+  int localbuf = 0;
 
   LOAD_BUFFER()
 
@@ -502,53 +565,41 @@
 encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
 {
-  int temp, temp2, temp3;
-  int nbits;
-  int r, code, size;
+  int temp, nbits, free_bits;
+  bit_buf_type put_buffer;
   JOCTET _buffer[BUFSIZE], *buffer;
-  size_t put_buffer;  int put_bits;
-  int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
-  size_t bytes, bytestocopy;  int localbuf = 0;
+  int localbuf = 0;
 
-  put_buffer = state->cur.put_buffer;
-  put_bits = state->cur.put_bits;
+  free_bits = state->cur.free_bits;
+  put_buffer = state->cur.put_buffer.c;
   LOAD_BUFFER()
 
   /* Encode the DC coefficient difference per section F.1.2.1 */
 
-  temp = temp2 = block[0] - last_dc_val;
+  temp = block[0] - last_dc_val;
 
   /* This is a well-known technique for obtaining the absolute value without a
    * branch.  It is derived from an assembly language technique presented in
    * "How to Optimize for the Pentium Processors", Copyright (c) 1996, 1997 by
-   * Agner Fog.
+   * Agner Fog.  This code assumes we are on a two's complement machine.
    */
-  temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
-  temp ^= temp3;
-  temp -= temp3;
-
-  /* For a negative input, want temp2 = bitwise complement of abs(input) */
-  /* This code assumes we are on a two's complement machine */
-  temp2 += temp3;
+  nbits = temp >> (CHAR_BIT * sizeof(int) - 1);
+  temp += nbits;
+  nbits ^= temp;
 
   /* Find the number of bits needed for the magnitude of the coefficient */
-  nbits = JPEG_NBITS(temp);
+  nbits = JPEG_NBITS(nbits);
 
-  /* Emit the Huffman-coded symbol for the number of bits */
-  code = dctbl->ehufco[nbits];
-  size = dctbl->ehufsi[nbits];
-  EMIT_BITS(code, size)
-
-  /* Mask off any extra bits in code */
-  temp2 &= (((JLONG)1) << nbits) - 1;
-
-  /* Emit that number of bits of the value, if positive, */
-  /* or the complement of its magnitude, if negative. */
-  EMIT_BITS(temp2, nbits)
+  /* Emit the Huffman-coded symbol for the number of bits.
+   * Emit that number of bits of the value, if positive,
+   * or the complement of its magnitude, if negative.
+   */
+  PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits])
 
   /* Encode the AC coefficients per section F.1.2.2 */
 
-  r = 0;                        /* r = run length of zeros */
+  {
+    int r = 0;                  /* r = run length of zeros */
 
 /* Manually unroll the k loop to eliminate the counter variable.  This
  * improves performance greatly on systems with a limited number of
@@ -556,51 +607,46 @@
  */
 #define kloop(jpeg_natural_order_of_k) { \
   if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
-    r++; \
+    r += 16; \
   } else { \
-    temp2 = temp; \
     /* Branch-less absolute value, bitwise complement, etc., same as above */ \
-    temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); \
-    temp ^= temp3; \
-    temp -= temp3; \
-    temp2 += temp3; \
-    nbits = JPEG_NBITS_NONZERO(temp); \
+    nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \
+    temp += nbits; \
+    nbits ^= temp; \
+    nbits = JPEG_NBITS_NONZERO(nbits); \
     /* if run length > 15, must emit special run-length-16 codes (0xF0) */ \
-    while (r > 15) { \
-      EMIT_BITS(code_0xf0, size_0xf0) \
-      r -= 16; \
+    while (r >= 16 * 16) { \
+      r -= 16 * 16; \
+      PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \
     } \
     /* Emit Huffman symbol for run length / number of bits */ \
-    temp3 = (r << 4) + nbits; \
-    code = actbl->ehufco[temp3]; \
-    size = actbl->ehufsi[temp3]; \
-    EMIT_CODE(code, size) \
+    r += nbits; \
+    PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \
     r = 0; \
   } \
 }
 
-  /* One iteration for each value in jpeg_natural_order[] */
-  kloop(1);   kloop(8);   kloop(16);  kloop(9);   kloop(2);   kloop(3);
-  kloop(10);  kloop(17);  kloop(24);  kloop(32);  kloop(25);  kloop(18);
-  kloop(11);  kloop(4);   kloop(5);   kloop(12);  kloop(19);  kloop(26);
-  kloop(33);  kloop(40);  kloop(48);  kloop(41);  kloop(34);  kloop(27);
-  kloop(20);  kloop(13);  kloop(6);   kloop(7);   kloop(14);  kloop(21);
-  kloop(28);  kloop(35);  kloop(42);  kloop(49);  kloop(56);  kloop(57);
-  kloop(50);  kloop(43);  kloop(36);  kloop(29);  kloop(22);  kloop(15);
-  kloop(23);  kloop(30);  kloop(37);  kloop(44);  kloop(51);  kloop(58);
-  kloop(59);  kloop(52);  kloop(45);  kloop(38);  kloop(31);  kloop(39);
-  kloop(46);  kloop(53);  kloop(60);  kloop(61);  kloop(54);  kloop(47);
-  kloop(55);  kloop(62);  kloop(63);
+    /* One iteration for each value in jpeg_natural_order[] */
+    kloop(1);   kloop(8);   kloop(16);  kloop(9);   kloop(2);   kloop(3);
+    kloop(10);  kloop(17);  kloop(24);  kloop(32);  kloop(25);  kloop(18);
+    kloop(11);  kloop(4);   kloop(5);   kloop(12);  kloop(19);  kloop(26);
+    kloop(33);  kloop(40);  kloop(48);  kloop(41);  kloop(34);  kloop(27);
+    kloop(20);  kloop(13);  kloop(6);   kloop(7);   kloop(14);  kloop(21);
+    kloop(28);  kloop(35);  kloop(42);  kloop(49);  kloop(56);  kloop(57);
+    kloop(50);  kloop(43);  kloop(36);  kloop(29);  kloop(22);  kloop(15);
+    kloop(23);  kloop(30);  kloop(37);  kloop(44);  kloop(51);  kloop(58);
+    kloop(59);  kloop(52);  kloop(45);  kloop(38);  kloop(31);  kloop(39);
+    kloop(46);  kloop(53);  kloop(60);  kloop(61);  kloop(54);  kloop(47);
+    kloop(55);  kloop(62);  kloop(63);
 
-  /* If the last coef(s) were zero, emit an end-of-block code */
-  if (r > 0) {
-    code = actbl->ehufco[0];
-    size = actbl->ehufsi[0];
-    EMIT_BITS(code, size)
+    /* If the last coef(s) were zero, emit an end-of-block code */
+    if (r > 0) {
+      PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
+    }
   }
 
-  state->cur.put_buffer = put_buffer;
-  state->cur.put_bits = put_bits;
+  state->cur.put_buffer.c = put_buffer;
+  state->cur.free_bits = free_bits;
   STORE_BUFFER()
 
   return TRUE;
@@ -647,8 +693,9 @@
   /* Load up working state */
   state.next_output_byte = cinfo->dest->next_output_byte;
   state.free_in_buffer = cinfo->dest->free_in_buffer;
-  ASSIGN_STATE(state.cur, entropy->saved);
+  state.cur = entropy->saved;
   state.cinfo = cinfo;
+  state.simd = entropy->simd;
 
   /* Emit restart marker if needed */
   if (cinfo->restart_interval) {
@@ -687,7 +734,7 @@
   /* Completed MCU, so update state */
   cinfo->dest->next_output_byte = state.next_output_byte;
   cinfo->dest->free_in_buffer = state.free_in_buffer;
-  ASSIGN_STATE(entropy->saved, state.cur);
+  entropy->saved = state.cur;
 
   /* Update restart-interval state too */
   if (cinfo->restart_interval) {
@@ -716,8 +763,9 @@
   /* Load up working state ... flush_bits needs it */
   state.next_output_byte = cinfo->dest->next_output_byte;
   state.free_in_buffer = cinfo->dest->free_in_buffer;
-  ASSIGN_STATE(state.cur, entropy->saved);
+  state.cur = entropy->saved;
   state.cinfo = cinfo;
+  state.simd = entropy->simd;
 
   /* Flush out the last data */
   if (!flush_bits(&state))
@@ -726,7 +774,7 @@
   /* Update state */
   cinfo->dest->next_output_byte = state.next_output_byte;
   cinfo->dest->free_in_buffer = state.free_in_buffer;
-  ASSIGN_STATE(entropy->saved, state.cur);
+  entropy->saved = state.cur;
 }
 
 
@@ -859,13 +907,14 @@
  * one bits (so that padding bits added at the end of a compressed segment
  * can't look like a valid code).  Because of the canonical ordering of
  * codewords, this just means that there must be an unused slot in the
- * longest codeword length category.  Section K.2 of the JPEG spec suggests
- * reserving such a slot by pretending that symbol 256 is a valid symbol
- * with count 1.  In theory that's not optimal; giving it count zero but
- * including it in the symbol set anyway should give a better Huffman code.
- * But the theoretically better code actually seems to come out worse in
- * practice, because it produces more all-ones bytes (which incur stuffed
- * zero bytes in the final file).  In any case the difference is tiny.
+ * longest codeword length category.  Annex K (Clause K.2) of
+ * Rec. ITU-T T.81 (1992) | ISO/IEC 10918-1:1994 suggests reserving such a slot
+ * by pretending that symbol 256 is a valid symbol with count 1.  In theory
+ * that's not optimal; giving it count zero but including it in the symbol set
+ * anyway should give a better Huffman code.  But the theoretically better code
+ * actually seems to come out worse in practice, because it produces more
+ * all-ones bytes (which incur stuffed zero bytes in the final file).  In any
+ * case the difference is tiny.
  *
  * The JPEG standard requires Huffman codes to be no more than 16 bits long.
  * If some symbols have a very small but nonzero probability, the Huffman tree
@@ -967,13 +1016,13 @@
 
   /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
    * Huffman procedure assigned any such lengths, we must adjust the coding.
-   * Here is what the JPEG spec says about how this next bit works:
-   * Since symbols are paired for the longest Huffman code, the symbols are
-   * removed from this length category two at a time.  The prefix for the pair
-   * (which is one bit shorter) is allocated to one of the pair; then,
-   * skipping the BITS entry for that prefix length, a code word from the next
-   * shortest nonzero BITS entry is converted into a prefix for two code words
-   * one bit longer.
+   * Here is what Rec. ITU-T T.81 | ISO/IEC 10918-1 says about how this next
+   * bit works: Since symbols are paired for the longest Huffman code, the
+   * symbols are removed from this length category two at a time.  The prefix
+   * for the pair (which is one bit shorter) is allocated to one of the pair;
+   * then, skipping the BITS entry for that prefix length, a code word from the
+   * next shortest nonzero BITS entry is converted into a prefix for two code
+   * words one bit longer.
    */
 
   for (i = MAX_CLEN; i > 16; i--) {
@@ -999,7 +1048,8 @@
 
   /* Return a list of the symbols sorted by code length */
   /* It's not real clear to me why we don't need to consider the codelength
-   * changes made above, but the JPEG spec seems to think this works.
+   * changes made above, but Rec. ITU-T T.81 | ISO/IEC 10918-1 seems to think
+   * this works.
    */
   p = 0;
   for (i = 1; i <= MAX_CLEN; i++) {
diff --git a/src/third_party/libjpeg-turbo/jcinit.c b/src/third_party/libjpeg-turbo/jcinit.c
index 78aa465..157353a 100644
--- a/src/third_party/libjpeg-turbo/jcinit.c
+++ b/src/third_party/libjpeg-turbo/jcinit.c
@@ -1,8 +1,10 @@
 /*
  * jcinit.c
  *
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * This file is part of the Independent JPEG Group's software.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -19,6 +21,7 @@
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
+#include "jpegcomp.h"
 
 
 /*
diff --git a/src/third_party/libjpeg-turbo/jcmaster.c b/src/third_party/libjpeg-turbo/jcmaster.c
index 8516f4b..c2b2600 100644
--- a/src/third_party/libjpeg-turbo/jcmaster.c
+++ b/src/third_party/libjpeg-turbo/jcmaster.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 2003-2010 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2016, D. R. Commander.
+ * Copyright (C) 2010, 2016, 2018, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -234,9 +234,9 @@
     Al = scanptr->Al;
     if (cinfo->progressive_mode) {
 #ifdef C_PROGRESSIVE_SUPPORTED
-      /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
-       * seems wrong: the upper bound ought to depend on data precision.
-       * Perhaps they really meant 0..N+1 for N-bit precision.
+      /* Rec. ITU-T T.81 | ISO/IEC 10918-1 simply gives the ranges 0..13 for Ah
+       * and Al, but that seems wrong: the upper bound ought to depend on data
+       * precision.  Perhaps they really meant 0..N+1 for N-bit precision.
        * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
        * out-of-range reconstructed DC values during the first DC scan,
        * which might cause problems for some decoders.
@@ -492,8 +492,8 @@
      */
     master->pass_type = output_pass;
     master->pass_number++;
-    /*FALLTHROUGH*/
 #endif
+    FALLTHROUGH                 /*FALLTHROUGH*/
   case output_pass:
     /* Do a data-output pass. */
     /* We need not repeat per-scan setup if prior optimization pass did it. */
diff --git a/src/third_party/libjpeg-turbo/jconfig.h b/src/third_party/libjpeg-turbo/jconfig.h
index 2959290..7d605e1 100644
--- a/src/third_party/libjpeg-turbo/jconfig.h
+++ b/src/third_party/libjpeg-turbo/jconfig.h
@@ -4,22 +4,24 @@
 #define JPEG_LIB_VERSION  62
 
 /* libjpeg-turbo version */
-#define LIBJPEG_TURBO_VERSION  1.5.91
+#define LIBJPEG_TURBO_VERSION  2.1.0
 
 /* libjpeg-turbo version in integer form */
-#define LIBJPEG_TURBO_VERSION_NUMBER  1005091
+#define LIBJPEG_TURBO_VERSION_NUMBER  2001000
 
 /* Support arithmetic encoding */
-#define C_ARITH_CODING_SUPPORTED
+#define C_ARITH_CODING_SUPPORTED 1
 
 /* Support arithmetic decoding */
-#define D_ARITH_CODING_SUPPORTED
+#define D_ARITH_CODING_SUPPORTED 1
 
 /* Support in-memory source/destination managers */
-#define MEM_SRCDST_SUPPORTED
+#define MEM_SRCDST_SUPPORTED 1
 
+#if !defined(STARBOARD)
 /* Use accelerated SIMD routines. */
-#define WITH_SIMD
+#define WITH_SIMD 1
+#endif
 
 #if defined(STARBOARD)
 #define NEED_STARBOARD_MEMORY
@@ -40,13 +42,13 @@
 #define BITS_IN_JSAMPLE  8      /* use 8 or 12 */
 
 /* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H
+#define HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H
+#define HAVE_STDDEF_H 1
 
 /* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H
+#define HAVE_STDLIB_H 1
 
 /* Define if you need to include <sys/types.h> to get size_t. */
 #define NEED_SYS_TYPES_H
@@ -56,10 +58,10 @@
 /* #undef NEED_BSD_STRINGS */
 
 /* Define to 1 if the system has the type `unsigned char'. */
-#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_CHAR 1
 
 /* Define to 1 if the system has the type `unsigned short'. */
-#define HAVE_UNSIGNED_SHORT
+#define HAVE_UNSIGNED_SHORT 1
 
 /* Compiler does not support pointers to undefined structures. */
 /* #undef INCOMPLETE_TYPES_BROKEN */
diff --git a/src/third_party/libjpeg-turbo/jconfig.h.in b/src/third_party/libjpeg-turbo/jconfig.h.in
index 2842754..d4284d9 100644
--- a/src/third_party/libjpeg-turbo/jconfig.h.in
+++ b/src/third_party/libjpeg-turbo/jconfig.h.in
@@ -10,16 +10,16 @@
 #define LIBJPEG_TURBO_VERSION_NUMBER  @LIBJPEG_TURBO_VERSION_NUMBER@
 
 /* Support arithmetic encoding */
-#cmakedefine C_ARITH_CODING_SUPPORTED
+#cmakedefine C_ARITH_CODING_SUPPORTED 1
 
 /* Support arithmetic decoding */
-#cmakedefine D_ARITH_CODING_SUPPORTED
+#cmakedefine D_ARITH_CODING_SUPPORTED 1
 
 /* Support in-memory source/destination managers */
-#cmakedefine MEM_SRCDST_SUPPORTED
+#cmakedefine MEM_SRCDST_SUPPORTED 1
 
 /* Use accelerated SIMD routines. */
-#cmakedefine WITH_SIMD
+#cmakedefine WITH_SIMD 1
 
 /*
  * Define BITS_IN_JSAMPLE as either
@@ -33,38 +33,33 @@
 #define BITS_IN_JSAMPLE  @BITS_IN_JSAMPLE@      /* use 8 or 12 */
 
 /* Define to 1 if you have the <locale.h> header file. */
-#cmakedefine HAVE_LOCALE_H
+#cmakedefine HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the <stddef.h> header file. */
-#cmakedefine HAVE_STDDEF_H
+#cmakedefine HAVE_STDDEF_H 1
 
 /* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H
+#cmakedefine HAVE_STDLIB_H 1
 
 /* Define if you need to include <sys/types.h> to get size_t. */
-#cmakedefine NEED_SYS_TYPES_H
+#cmakedefine NEED_SYS_TYPES_H 1
 
 /* Define if you have BSD-like bzero and bcopy in <strings.h> rather than
    memset/memcpy in <string.h>. */
-#cmakedefine NEED_BSD_STRINGS
+#cmakedefine NEED_BSD_STRINGS 1
 
 /* Define to 1 if the system has the type `unsigned char'. */
-#cmakedefine HAVE_UNSIGNED_CHAR
+#cmakedefine HAVE_UNSIGNED_CHAR 1
 
 /* Define to 1 if the system has the type `unsigned short'. */
-#cmakedefine HAVE_UNSIGNED_SHORT
+#cmakedefine HAVE_UNSIGNED_SHORT 1
 
 /* Compiler does not support pointers to undefined structures. */
-#cmakedefine INCOMPLETE_TYPES_BROKEN
+#cmakedefine INCOMPLETE_TYPES_BROKEN 1
 
 /* Define if your (broken) compiler shifts signed values as if they were
    unsigned. */
-#cmakedefine RIGHT_SHIFT_IS_UNSIGNED
-
-/* Define to 1 if type `char' is unsigned and you are not using gcc.  */
-#ifndef __CHAR_UNSIGNED__
-  #cmakedefine __CHAR_UNSIGNED__
-#endif
+#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
diff --git a/src/third_party/libjpeg-turbo/jconfig.txt b/src/third_party/libjpeg-turbo/jconfig.txt
index 90cd724..21f35c1 100644
--- a/src/third_party/libjpeg-turbo/jconfig.txt
+++ b/src/third_party/libjpeg-turbo/jconfig.txt
@@ -42,12 +42,6 @@
  */
 /* #define const */
 
-/* Define this if an ordinary "char" type is unsigned.
- * If you're not sure, leaving it undefined will work at some cost in speed.
- * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
- */
-#undef __CHAR_UNSIGNED__
-
 /* Define this if your system has an ANSI-conforming <stddef.h> file.
  */
 #define HAVE_STDDEF_H
@@ -118,7 +112,6 @@
 #define BMP_SUPPORTED           /* BMP image file format */
 #define GIF_SUPPORTED           /* GIF image file format */
 #define PPM_SUPPORTED           /* PBMPLUS PPM/PGM image file format */
-#undef RLE_SUPPORTED            /* Utah RLE image file format */
 #define TARGA_SUPPORTED         /* Targa image file format */
 
 /* Define this if you want to name both input and output files on the command
diff --git a/src/third_party/libjpeg-turbo/jconfigint.h b/src/third_party/libjpeg-turbo/jconfigint.h
index 037cffa..c0ae709 100644
--- a/src/third_party/libjpeg-turbo/jconfigint.h
+++ b/src/third_party/libjpeg-turbo/jconfigint.h
@@ -1,28 +1,68 @@
-/* jconfigint.h.  Generated from jconfigint.h.in by configure.  */
 /* libjpeg-turbo build number */
-#define BUILD ""
+#define BUILD  ""
+
+/* Compiler's inline keyword */
+#undef inline
 
 /* How to obtain function inlining. */
 #ifndef INLINE
 #if defined(__GNUC__)
-#define INLINE inline __attribute__((always_inline))
+#define INLINE  inline __attribute__((always_inline))
 #elif defined(_MSC_VER)
-#define INLINE __forceinline
+#define INLINE  __forceinline
 #else
 #define INLINE
 #endif
 #endif
 
+#if !defined(STARBOARD)
+/* How to obtain thread-local storage */
+#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
+#define THREAD_LOCAL  __declspec(thread)
+#else
+#define THREAD_LOCAL  __thread
+#endif
+#endif
+
 /* Define to the full name of this package. */
-#define PACKAGE_NAME "libjpeg-turbo"
+#define PACKAGE_NAME  "libjpeg-turbo"
 
 /* Version number of package */
-#define VERSION "1.4.90"
+#define VERSION  "2.1.0"
 
 /* The size of `size_t', as computed by sizeof. */
 #if __WORDSIZE==64 || defined(_WIN64)
-#define SIZEOF_SIZE_T 8
+#define SIZEOF_SIZE_T  8
 #else
-#define SIZEOF_SIZE_T 4
+#define SIZEOF_SIZE_T  4
 #endif
-                                                                                
+
+/* Define if your compiler has __builtin_ctzl() and sizeof(unsigned long) == sizeof(size_t). */
+#if defined(__GNUC__)
+#define HAVE_BUILTIN_CTZL
+#endif
+
+#if !defined(STARBOARD)
+/* Define to 1 if you have the <intrin.h> header file. */
+#if defined(_MSC_VER)
+#define HAVE_INTRIN_H  1
+#endif
+#endif
+
+#if defined(_MSC_VER) && defined(HAVE_INTRIN_H)
+#if (SIZEOF_SIZE_T == 8)
+#define HAVEBITSCANFORWARD64
+#elif (SIZEOF_SIZE_T == 4)
+#define HAVEBITSCANFORWARD
+#endif
+#endif
+
+#if defined(__has_attribute)
+#if __has_attribute(fallthrough)
+#define FALLTHROUGH __attribute__((fallthrough));
+#else
+#define FALLTHROUGH
+#endif
+#else
+#define FALLTHROUGH
+#endif
diff --git a/src/third_party/libjpeg-turbo/jconfigint.h.in b/src/third_party/libjpeg-turbo/jconfigint.h.in
index 55df053..d087d7b 100644
--- a/src/third_party/libjpeg-turbo/jconfigint.h.in
+++ b/src/third_party/libjpeg-turbo/jconfigint.h.in
@@ -7,6 +7,9 @@
 /* How to obtain function inlining. */
 #define INLINE  @INLINE@
 
+/* How to obtain thread-local storage */
+#define THREAD_LOCAL  @THREAD_LOCAL@
+
 /* Define to the full name of this package. */
 #define PACKAGE_NAME  "@CMAKE_PROJECT_NAME@"
 
@@ -29,3 +32,13 @@
 #define HAVE_BITSCANFORWARD
 #endif
 #endif
+
+#if defined(__has_attribute)
+#if __has_attribute(fallthrough)
+#define FALLTHROUGH  __attribute__((fallthrough));
+#else
+#define FALLTHROUGH
+#endif
+#else
+#define FALLTHROUGH
+#endif
diff --git a/src/third_party/libjpeg-turbo/jcparam.c b/src/third_party/libjpeg-turbo/jcparam.c
index bcea927..5bc7174 100644
--- a/src/third_party/libjpeg-turbo/jcparam.c
+++ b/src/third_party/libjpeg-turbo/jcparam.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1998, Thomas G. Lane.
  * Modified 2003-2008 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009-2011, D. R. Commander.
+ * Copyright (C) 2009-2011, 2018, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -65,7 +65,8 @@
 }
 
 
-/* These are the sample quantization tables given in JPEG spec section K.1.
+/* These are the sample quantization tables given in Annex K (Clause K.1) of
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  * The spec says that the values given produce "good" quality, and
  * when divided by 2, "very good" quality.
  */
diff --git a/src/third_party/libjpeg-turbo/jcphuff.c b/src/third_party/libjpeg-turbo/jcphuff.c
index 024d3af..9bf9612 100644
--- a/src/third_party/libjpeg-turbo/jcphuff.c
+++ b/src/third_party/libjpeg-turbo/jcphuff.c
@@ -4,8 +4,9 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1995-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2011, 2015, 2018, D. R. Commander.
+ * Copyright (C) 2011, 2015, 2018, 2021, D. R. Commander.
  * Copyright (C) 2016, 2018, Matthieu Darbois.
+ * Copyright (C) 2020, Arm Limited.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -43,23 +44,28 @@
  * memory footprint by 64k, which is important for some mobile applications
  * that create many isolated instances of libjpeg-turbo (web browsers, for
  * instance.)  This may improve performance on some mobile platforms as well.
- * This feature is enabled by default only on ARM processors, because some x86
+ * This feature is enabled by default only on Arm processors, because some x86
  * chips have a slow implementation of bsr, and the use of clz/bsr cannot be
  * shown to have a significant performance impact even on the x86 chips that
- * have a fast implementation of it.  When building for ARMv6, you can
+ * have a fast implementation of it.  When building for Armv6, you can
  * explicitly disable the use of clz/bsr by adding -mthumb to the compiler
  * flags (this defines __thumb__).
  */
 
 /* NOTE: Both GCC and Clang define __GNUC__ */
-#if defined __GNUC__ && (defined __arm__ || defined __aarch64__)
-#if !defined __thumb__ || defined __thumb2__
+#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
+    defined(_M_ARM) || defined(_M_ARM64)
+#if !defined(__thumb__) || defined(__thumb2__)
 #define USE_CLZ_INTRINSIC
 #endif
 #endif
 
 #ifdef USE_CLZ_INTRINSIC
+#if defined(_MSC_VER) && !defined(__clang__)
+#define JPEG_NBITS_NONZERO(x)  (32 - _CountLeadingZeros(x))
+#else
 #define JPEG_NBITS_NONZERO(x)  (32 - __builtin_clz(x))
+#endif
 #define JPEG_NBITS(x)          (x ? JPEG_NBITS_NONZERO(x) : 0)
 #else
 #include "jpeg_nbits_table.h"
@@ -169,24 +175,26 @@
 METHODDEF(int)
 count_zeroes(size_t *x)
 {
-  int result;
 #if defined(HAVE_BUILTIN_CTZL)
+  int result;
   result = __builtin_ctzl(*x);
   *x >>= result;
 #elif defined(HAVE_BITSCANFORWARD64)
+  unsigned long result;
   _BitScanForward64(&result, *x);
   *x >>= result;
 #elif defined(HAVE_BITSCANFORWARD)
+  unsigned long result;
   _BitScanForward(&result, *x);
   *x >>= result;
 #else
-  result = 0;
+  int result = 0;
   while ((*x & 1) == 0) {
     ++result;
     *x >>= 1;
   }
 #endif
-  return result;
+  return (int)result;
 }
 
 
@@ -860,7 +868,7 @@
 
 #define ENCODE_COEFS_AC_REFINE(label) { \
   while (zerobits) { \
-    int idx = count_zeroes(&zerobits); \
+    idx = count_zeroes(&zerobits); \
     r += idx; \
     cabsvalue += idx; \
     signbits >>= idx; \
@@ -917,7 +925,7 @@
 encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy;
-  register int temp, r;
+  register int temp, r, idx;
   char *BR_buffer;
   unsigned int BR;
   int Sl = cinfo->Se - cinfo->Ss + 1;
@@ -968,7 +976,7 @@
 
   if (zerobits) {
     int diff = ((absvalues + DCTSIZE2 / 2) - cabsvalue);
-    int idx = count_zeroes(&zerobits);
+    idx = count_zeroes(&zerobits);
     signbits >>= idx;
     idx += diff;
     r += idx;
diff --git a/src/third_party/libjpeg-turbo/jcsample.c b/src/third_party/libjpeg-turbo/jcsample.c
index bd27b84..e8515eb 100644
--- a/src/third_party/libjpeg-turbo/jcsample.c
+++ b/src/third_party/libjpeg-turbo/jcsample.c
@@ -6,7 +6,7 @@
  * libjpeg-turbo Modifications:
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  * Copyright (C) 2014, MIPS Technologies, Inc., California.
- * Copyright (C) 2015, D. R. Commander.
+ * Copyright (C) 2015, 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -103,7 +103,7 @@
   if (numcols > 0) {
     for (row = 0; row < num_rows; row++) {
       ptr = image_data[row] + input_cols;
-      pixval = ptr[-1];         /* don't need GETJSAMPLE() here */
+      pixval = ptr[-1];
       for (count = numcols; count > 0; count--)
         *ptr++ = pixval;
     }
@@ -174,7 +174,7 @@
       for (v = 0; v < v_expand; v++) {
         inptr = input_data[inrow + v] + outcol_h;
         for (h = 0; h < h_expand; h++) {
-          outvalue += (JLONG)GETJSAMPLE(*inptr++);
+          outvalue += (JLONG)(*inptr++);
         }
       }
       *outptr++ = (JSAMPLE)((outvalue + numpix2) / numpix);
@@ -237,8 +237,7 @@
     inptr = input_data[outrow];
     bias = 0;                   /* bias = 0,1,0,1,... for successive samples */
     for (outcol = 0; outcol < output_cols; outcol++) {
-      *outptr++ =
-        (JSAMPLE)((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) + bias) >> 1);
+      *outptr++ = (JSAMPLE)((inptr[0] + inptr[1] + bias) >> 1);
       bias ^= 1;                /* 0=>1, 1=>0 */
       inptr += 2;
     }
@@ -277,8 +276,7 @@
     bias = 1;                   /* bias = 1,2,1,2,... for successive samples */
     for (outcol = 0; outcol < output_cols; outcol++) {
       *outptr++ =
-        (JSAMPLE)((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
-                   GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) + bias) >> 2);
+        (JSAMPLE)((inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1] + bias) >> 2);
       bias ^= 3;                /* 1=>2, 2=>1 */
       inptr0 += 2;  inptr1 += 2;
     }
@@ -337,33 +335,25 @@
     below_ptr = input_data[inrow + 2];
 
     /* Special case for first column: pretend column -1 is same as column 0 */
-    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
-                GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
-    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
-               GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
-               GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
-               GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
+    membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
+    neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
+               inptr0[0] + inptr0[2] + inptr1[0] + inptr1[2];
     neighsum += neighsum;
-    neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
-                GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
+    neighsum += above_ptr[0] + above_ptr[2] + below_ptr[0] + below_ptr[2];
     membersum = membersum * memberscale + neighsum * neighscale;
     *outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
     inptr0 += 2;  inptr1 += 2;  above_ptr += 2;  below_ptr += 2;
 
     for (colctr = output_cols - 2; colctr > 0; colctr--) {
       /* sum of pixels directly mapped to this output element */
-      membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
-                  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+      membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
       /* sum of edge-neighbor pixels */
-      neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
-                 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
-                 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
-                 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
+      neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
+                 inptr0[-1] + inptr0[2] + inptr1[-1] + inptr1[2];
       /* The edge-neighbors count twice as much as corner-neighbors */
       neighsum += neighsum;
       /* Add in the corner-neighbors */
-      neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
-                  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
+      neighsum += above_ptr[-1] + above_ptr[2] + below_ptr[-1] + below_ptr[2];
       /* form final output scaled up by 2^16 */
       membersum = membersum * memberscale + neighsum * neighscale;
       /* round, descale and output it */
@@ -372,15 +362,11 @@
     }
 
     /* Special case for last column */
-    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
-                GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
-    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
-               GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
-               GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
-               GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
+    membersum = inptr0[0] + inptr0[1] + inptr1[0] + inptr1[1];
+    neighsum = above_ptr[0] + above_ptr[1] + below_ptr[0] + below_ptr[1] +
+               inptr0[-1] + inptr0[1] + inptr1[-1] + inptr1[1];
     neighsum += neighsum;
-    neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
-                GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
+    neighsum += above_ptr[-1] + above_ptr[1] + below_ptr[-1] + below_ptr[1];
     membersum = membersum * memberscale + neighsum * neighscale;
     *outptr = (JSAMPLE)((membersum + 32768) >> 16);
 
@@ -429,21 +415,18 @@
     below_ptr = input_data[outrow + 1];
 
     /* Special case for first column */
-    colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
-             GETJSAMPLE(*inptr);
-    membersum = GETJSAMPLE(*inptr++);
-    nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
-                 GETJSAMPLE(*inptr);
+    colsum = (*above_ptr++) + (*below_ptr++) + inptr[0];
+    membersum = *inptr++;
+    nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
     neighsum = colsum + (colsum - membersum) + nextcolsum;
     membersum = membersum * memberscale + neighsum * neighscale;
     *outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
     lastcolsum = colsum;  colsum = nextcolsum;
 
     for (colctr = output_cols - 2; colctr > 0; colctr--) {
-      membersum = GETJSAMPLE(*inptr++);
+      membersum = *inptr++;
       above_ptr++;  below_ptr++;
-      nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
-                   GETJSAMPLE(*inptr);
+      nextcolsum = above_ptr[0] + below_ptr[0] + inptr[0];
       neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
       membersum = membersum * memberscale + neighsum * neighscale;
       *outptr++ = (JSAMPLE)((membersum + 32768) >> 16);
@@ -451,7 +434,7 @@
     }
 
     /* Special case for last column */
-    membersum = GETJSAMPLE(*inptr);
+    membersum = *inptr;
     neighsum = lastcolsum + (colsum - membersum) + colsum;
     membersum = membersum * memberscale + neighsum * neighscale;
     *outptr = (JSAMPLE)((membersum + 32768) >> 16);
diff --git a/src/third_party/libjpeg-turbo/jcstest.c b/src/third_party/libjpeg-turbo/jcstest.c
index 9d2bda3..3155aad 100644
--- a/src/third_party/libjpeg-turbo/jcstest.c
+++ b/src/third_party/libjpeg-turbo/jcstest.c
@@ -28,6 +28,7 @@
 
 /* This program demonstrates how to check for the colorspace extension
    capabilities of libjpeg-turbo at both compile time and run time. */
+
 #ifdef STARBOARD
 #include "starboard/client_porting/poem/stdio_poem.h"
 #else
diff --git a/src/third_party/libjpeg-turbo/jctrans.c b/src/third_party/libjpeg-turbo/jctrans.c
index ce70a30..ab6a218 100644
--- a/src/third_party/libjpeg-turbo/jctrans.c
+++ b/src/third_party/libjpeg-turbo/jctrans.c
@@ -4,8 +4,8 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1995-1998, Thomas G. Lane.
  * Modified 2000-2009 by Guido Vollbeding.
- * It was modified by The libjpeg-turbo Project to include only code relevant
- * to libjpeg-turbo.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -17,6 +17,7 @@
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
+#include "jpegcomp.h"
 
 
 /* Forward declarations */
diff --git a/src/third_party/libjpeg-turbo/jdapimin.c b/src/third_party/libjpeg-turbo/jdapimin.c
index 21a41d2..4609b13 100644
--- a/src/third_party/libjpeg-turbo/jdapimin.c
+++ b/src/third_party/libjpeg-turbo/jdapimin.c
@@ -23,6 +23,7 @@
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jdmaster.h"
+#include "jconfigint.h"
 
 
 /*
@@ -308,7 +309,7 @@
     /* Initialize application's data source module */
     (*cinfo->src->init_source) (cinfo);
     cinfo->global_state = DSTATE_INHEADER;
-    /*FALLTHROUGH*/
+    FALLTHROUGH                 /*FALLTHROUGH*/
   case DSTATE_INHEADER:
     retcode = (*cinfo->inputctl->consume_input) (cinfo);
     if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
diff --git a/src/third_party/libjpeg-turbo/jdapistd.c b/src/third_party/libjpeg-turbo/jdapistd.c
index 0e0642b..695a620 100644
--- a/src/third_party/libjpeg-turbo/jdapistd.c
+++ b/src/third_party/libjpeg-turbo/jdapistd.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2015-2017, D. R. Commander.
+ * Copyright (C) 2010, 2015-2020, D. R. Commander.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -21,6 +21,8 @@
 #include "jinclude.h"
 #include "jdmainct.h"
 #include "jdcoefct.h"
+#include "jdmaster.h"
+#include "jdmerge.h"
 #include "jdsample.h"
 #include "jmemsys.h"
 
@@ -316,23 +318,41 @@
 read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
 {
   JDIMENSION n;
+  my_master_ptr master = (my_master_ptr)cinfo->master;
+  JSAMPLE dummy_sample[1] = { 0 };
+  JSAMPROW dummy_row = dummy_sample;
+  JSAMPARRAY scanlines = NULL;
   void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                          JDIMENSION input_row, JSAMPARRAY output_buf,
-                         int num_rows);
+                         int num_rows) = NULL;
   void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
                           JSAMPARRAY output_buf, int num_rows) = NULL;
 
-  color_convert = cinfo->cconvert->color_convert;
-  cinfo->cconvert->color_convert = noop_convert;
+  if (cinfo->cconvert && cinfo->cconvert->color_convert) {
+    color_convert = cinfo->cconvert->color_convert;
+    cinfo->cconvert->color_convert = noop_convert;
+    /* This just prevents UBSan from complaining about adding 0 to a NULL
+     * pointer.  The pointer isn't actually used.
+     */
+    scanlines = &dummy_row;
+  }
+
   if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
     color_quantize = cinfo->cquantize->color_quantize;
     cinfo->cquantize->color_quantize = noop_quantize;
   }
 
-  for (n = 0; n < num_lines; n++)
-    jpeg_read_scanlines(cinfo, NULL, 1);
+  if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) {
+    my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+    scanlines = &upsample->spare_row;
+  }
 
-  cinfo->cconvert->color_convert = color_convert;
+  for (n = 0; n < num_lines; n++)
+    jpeg_read_scanlines(cinfo, scanlines, 1);
+
+  if (color_convert)
+    cinfo->cconvert->color_convert = color_convert;
+
   if (color_quantize)
     cinfo->cquantize->color_quantize = color_quantize;
 }
@@ -348,6 +368,12 @@
 {
   JDIMENSION rows_left;
   my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
+  my_master_ptr master = (my_master_ptr)cinfo->master;
+
+  if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) {
+    read_and_discard_scanlines(cinfo, rows);
+    return;
+  }
 
   /* Increment the counter to the next row group after the skipped rows. */
   main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor;
@@ -377,21 +403,27 @@
 {
   my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
   my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
+  my_master_ptr master = (my_master_ptr)cinfo->master;
   my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
   JDIMENSION i, x;
   int y;
   JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row;
   JDIMENSION lines_to_skip, lines_to_read;
 
+  /* Two-pass color quantization is not supported. */
+  if (cinfo->quantize_colors && cinfo->two_pass_quantize)
+    ERREXIT(cinfo, JERR_NOTIMPL);
+
   if (cinfo->global_state != DSTATE_SCANNING)
     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 
   /* Do not skip past the bottom of the image. */
   if (cinfo->output_scanline + num_lines >= cinfo->output_height) {
+    num_lines = cinfo->output_height - cinfo->output_scanline;
     cinfo->output_scanline = cinfo->output_height;
     (*cinfo->inputctl->finish_input_pass) (cinfo);
     cinfo->inputctl->eoi_reached = TRUE;
-    return cinfo->output_height - cinfo->output_scanline;
+    return num_lines;
   }
 
   if (num_lines == 0)
@@ -440,8 +472,10 @@
     main_ptr->buffer_full = FALSE;
     main_ptr->rowgroup_ctr = 0;
     main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
-    upsample->next_row_out = cinfo->max_v_samp_factor;
-    upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+    if (!master->using_merged_upsample) {
+      upsample->next_row_out = cinfo->max_v_samp_factor;
+      upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+    }
   }
 
   /* Skipping is much simpler when context rows are not required. */
@@ -453,8 +487,10 @@
       cinfo->output_scanline += lines_left_in_iMCU_row;
       main_ptr->buffer_full = FALSE;
       main_ptr->rowgroup_ctr = 0;
-      upsample->next_row_out = cinfo->max_v_samp_factor;
-      upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+      if (!master->using_merged_upsample) {
+        upsample->next_row_out = cinfo->max_v_samp_factor;
+        upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+      }
     }
   }
 
@@ -479,7 +515,7 @@
     if (cinfo->upsample->need_context_rows) {
       cinfo->output_scanline += lines_to_skip;
       cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
-      main_ptr->iMCU_row_ctr += lines_after_iMCU_row / lines_per_iMCU_row;
+      main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row;
       /* It is complex to properly move to the middle of a context block, so
        * read the remaining lines instead of skipping them.
        */
@@ -489,7 +525,8 @@
       cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
       increment_simple_rowgroup_ctr(cinfo, lines_to_read);
     }
-    upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+    if (!master->using_merged_upsample)
+      upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
     return num_lines;
   }
 
@@ -501,6 +538,8 @@
          * decoded coefficients.  This is ~5% faster for large subsets, but
          * it's tough to tell a difference for smaller images.
          */
+        if (!cinfo->entropy->insufficient_data)
+          cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
         (*cinfo->entropy->decode_mcu) (cinfo, NULL);
       }
     }
@@ -530,7 +569,8 @@
    * bit odd, since "rows_to_go" seems to be redundantly keeping track of
    * output_scanline.
    */
-  upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+  if (!master->using_merged_upsample)
+    upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
 
   /* Always skip the requested number of lines. */
   return num_lines;
diff --git a/src/third_party/libjpeg-turbo/jdarith.c b/src/third_party/libjpeg-turbo/jdarith.c
index a67995b..7f0d3a7 100644
--- a/src/third_party/libjpeg-turbo/jdarith.c
+++ b/src/third_party/libjpeg-turbo/jdarith.c
@@ -4,16 +4,19 @@
  * This file was part of the Independent JPEG Group's software:
  * Developed 1997-2015 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015-2017, D. R. Commander.
+ * Copyright (C) 2015-2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
- * This file contains portable arithmetic entropy decoding routines for JPEG
- * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
+ * This file contains portable arithmetic entropy encoding routines for JPEG
+ * (implementing Recommendation ITU-T T.81 | ISO/IEC 10918-1).
  *
  * Both sequential and progressive modes are supported in this single module.
  *
  * Suspension is not currently supported in this module.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  */
 
 #define JPEG_INTERNALS
@@ -77,7 +80,7 @@
     if (!(*src->fill_input_buffer) (cinfo))
       ERREXIT(cinfo, JERR_CANT_SUSPEND);
   src->bytes_in_buffer--;
-  return GETJOCTET(*src->next_input_byte++);
+  return *src->next_input_byte++;
 }
 
 
@@ -662,8 +665,16 @@
     for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
       int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
       int *coef_bit_ptr = &cinfo->coef_bits[cindex][0];
+      int *prev_coef_bit_ptr =
+        &cinfo->coef_bits[cindex + cinfo->num_components][0];
       if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
         WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+      for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
+        if (cinfo->input_scan_number > 1)
+          prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
+        else
+          prev_coef_bit_ptr[coefi] = 0;
+      }
       for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
         int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
         if (cinfo->Ah != expected)
@@ -724,6 +735,7 @@
   entropy->c = 0;
   entropy->a = 0;
   entropy->ct = -16;    /* force reading 2 initial bytes to fill C */
+  entropy->pub.insufficient_data = FALSE;
 
   /* Initialize restart counter */
   entropy->restarts_to_go = cinfo->restart_interval;
@@ -760,7 +772,7 @@
     int *coef_bit_ptr, ci;
     cinfo->coef_bits = (int (*)[DCTSIZE2])
       (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                  cinfo->num_components * DCTSIZE2 *
+                                  cinfo->num_components * 2 * DCTSIZE2 *
                                   sizeof(int));
     coef_bit_ptr = &cinfo->coef_bits[0][0];
     for (ci = 0; ci < cinfo->num_components; ci++)
diff --git a/src/third_party/libjpeg-turbo/jdatadst-tj.c b/src/third_party/libjpeg-turbo/jdatadst-tj.c
index 5fab80b..9bdc7c8 100644
--- a/src/third_party/libjpeg-turbo/jdatadst-tj.c
+++ b/src/third_party/libjpeg-turbo/jdatadst-tj.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * Modified 2009-2012 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2011, 2014, 2016, D. R. Commander.
+ * Copyright (C) 2011, 2014, 2016, 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -32,6 +32,9 @@
 #endif
 #endif
 
+void jpeg_mem_dest_tj(j_compress_ptr cinfo, unsigned char **outbuffer,
+                      unsigned long *outsize, boolean alloc);
+
 
 #define OUTPUT_BUF_SIZE  4096   /* choose an efficiently fwrite'able size */
 
@@ -105,8 +108,7 @@
 
   MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
 
-  if (dest->newbuffer != NULL)
-    free(dest->newbuffer);
+  free(dest->newbuffer);
 
   dest->newbuffer = nextbuffer;
 
diff --git a/src/third_party/libjpeg-turbo/jdatadst.c b/src/third_party/libjpeg-turbo/jdatadst.c
index 3168b96..246fffb 100644
--- a/src/third_party/libjpeg-turbo/jdatadst.c
+++ b/src/third_party/libjpeg-turbo/jdatadst.c
@@ -143,8 +143,7 @@
 
   MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
 
-  if (dest->newbuffer != NULL)
-    free(dest->newbuffer);
+  free(dest->newbuffer);
 
   dest->newbuffer = nextbuffer;
 
diff --git a/src/third_party/libjpeg-turbo/jdatasrc-tj.c b/src/third_party/libjpeg-turbo/jdatasrc-tj.c
index 1c71307..69fb5ea 100644
--- a/src/third_party/libjpeg-turbo/jdatasrc-tj.c
+++ b/src/third_party/libjpeg-turbo/jdatasrc-tj.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * Modified 2009-2011 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2011, 2016, D. R. Commander.
+ * Copyright (C) 2011, 2016, 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -23,6 +23,9 @@
 #include "jpeglib.h"
 #include "jerror.h"
 
+void jpeg_mem_src_tj(j_decompress_ptr cinfo, const unsigned char *inbuffer,
+                     unsigned long insize);
+
 
 /*
  * Initialize source --- called by jpeg_read_header
diff --git a/src/third_party/libjpeg-turbo/jdcoefct.c b/src/third_party/libjpeg-turbo/jdcoefct.c
index 723a9ac..15e6cde 100644
--- a/src/third_party/libjpeg-turbo/jdcoefct.c
+++ b/src/third_party/libjpeg-turbo/jdcoefct.c
@@ -5,8 +5,8 @@
  * Copyright (C) 1994-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2010, 2015-2016, D. R. Commander.
- * Copyright (C) 2015, Google, Inc.
+ * Copyright (C) 2010, 2015-2016, 2019-2020, D. R. Commander.
+ * Copyright (C) 2015, 2020, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -102,6 +102,8 @@
       /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
       jzero_far((void *)coef->MCU_buffer[0],
                 (size_t)(cinfo->blocks_in_MCU * sizeof(JBLOCK)));
+      if (!cinfo->entropy->insufficient_data)
+        cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
       if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
         /* Suspension forced; update state counters and exit */
         coef->MCU_vert_offset = yoffset;
@@ -227,6 +229,8 @@
           }
         }
       }
+      if (!cinfo->entropy->insufficient_data)
+        cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row;
       /* Try to fetch the MCU. */
       if (!(*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
         /* Suspension forced; update state counters and exit */
@@ -326,19 +330,22 @@
 #ifdef BLOCK_SMOOTHING_SUPPORTED
 
 /*
- * This code applies interblock smoothing as described by section K.8
- * of the JPEG standard: the first 5 AC coefficients are estimated from
- * the DC values of a DCT block and its 8 neighboring blocks.
+ * This code applies interblock smoothing; the first 9 AC coefficients are
+ * estimated from the DC values of a DCT block and its 24 neighboring blocks.
  * We apply smoothing only for progressive JPEG decoding, and only if
  * the coefficients it can estimate are not yet known to full precision.
  */
 
-/* Natural-order array positions of the first 5 zigzag-order coefficients */
+/* Natural-order array positions of the first 9 zigzag-order coefficients */
 #define Q01_POS  1
 #define Q10_POS  8
 #define Q20_POS  16
 #define Q11_POS  9
 #define Q02_POS  2
+#define Q03_POS  3
+#define Q12_POS  10
+#define Q21_POS  17
+#define Q30_POS  24
 
 /*
  * Determine whether block smoothing is applicable and safe.
@@ -356,8 +363,8 @@
   int ci, coefi;
   jpeg_component_info *compptr;
   JQUANT_TBL *qtable;
-  int *coef_bits;
-  int *coef_bits_latch;
+  int *coef_bits, *prev_coef_bits;
+  int *coef_bits_latch, *prev_coef_bits_latch;
 
   if (!cinfo->progressive_mode || cinfo->coef_bits == NULL)
     return FALSE;
@@ -366,34 +373,47 @@
   if (coef->coef_bits_latch == NULL)
     coef->coef_bits_latch = (int *)
       (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                  cinfo->num_components *
+                                  cinfo->num_components * 2 *
                                   (SAVED_COEFS * sizeof(int)));
   coef_bits_latch = coef->coef_bits_latch;
+  prev_coef_bits_latch =
+    &coef->coef_bits_latch[cinfo->num_components * SAVED_COEFS];
 
   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
        ci++, compptr++) {
     /* All components' quantization values must already be latched. */
     if ((qtable = compptr->quant_table) == NULL)
       return FALSE;
-    /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
+    /* Verify DC & first 9 AC quantizers are nonzero to avoid zero-divide. */
     if (qtable->quantval[0] == 0 ||
         qtable->quantval[Q01_POS] == 0 ||
         qtable->quantval[Q10_POS] == 0 ||
         qtable->quantval[Q20_POS] == 0 ||
         qtable->quantval[Q11_POS] == 0 ||
-        qtable->quantval[Q02_POS] == 0)
+        qtable->quantval[Q02_POS] == 0 ||
+        qtable->quantval[Q03_POS] == 0 ||
+        qtable->quantval[Q12_POS] == 0 ||
+        qtable->quantval[Q21_POS] == 0 ||
+        qtable->quantval[Q30_POS] == 0)
       return FALSE;
     /* DC values must be at least partly known for all components. */
     coef_bits = cinfo->coef_bits[ci];
+    prev_coef_bits = cinfo->coef_bits[ci + cinfo->num_components];
     if (coef_bits[0] < 0)
       return FALSE;
+    coef_bits_latch[0] = coef_bits[0];
     /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
-    for (coefi = 1; coefi <= 5; coefi++) {
+    for (coefi = 1; coefi < SAVED_COEFS; coefi++) {
+      if (cinfo->input_scan_number > 1)
+        prev_coef_bits_latch[coefi] = prev_coef_bits[coefi];
+      else
+        prev_coef_bits_latch[coefi] = -1;
       coef_bits_latch[coefi] = coef_bits[coefi];
       if (coef_bits[coefi] != 0)
         smoothing_useful = TRUE;
     }
     coef_bits_latch += SAVED_COEFS;
+    prev_coef_bits_latch += SAVED_COEFS;
   }
 
   return smoothing_useful;
@@ -412,17 +432,20 @@
   JDIMENSION block_num, last_block_column;
   int ci, block_row, block_rows, access_rows;
   JBLOCKARRAY buffer;
-  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
+  JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row;
+  JBLOCKROW next_block_row, next_next_block_row;
   JSAMPARRAY output_ptr;
   JDIMENSION output_col;
   jpeg_component_info *compptr;
   inverse_DCT_method_ptr inverse_DCT;
-  boolean first_row, last_row;
+  boolean change_dc;
   JCOEF *workspace;
   int *coef_bits;
   JQUANT_TBL *quanttbl;
-  JLONG Q00, Q01, Q02, Q10, Q11, Q20, num;
-  int DC1, DC2, DC3, DC4, DC5, DC6, DC7, DC8, DC9;
+  JLONG Q00, Q01, Q02, Q03 = 0, Q10, Q11, Q12 = 0, Q20, Q21 = 0, Q30 = 0, num;
+  int DC01, DC02, DC03, DC04, DC05, DC06, DC07, DC08, DC09, DC10, DC11, DC12,
+      DC13, DC14, DC15, DC16, DC17, DC18, DC19, DC20, DC21, DC22, DC23, DC24,
+      DC25;
   int Al, pred;
 
   /* Keep a local variable to avoid looking it up more than once */
@@ -434,10 +457,10 @@
     if (cinfo->input_scan_number == cinfo->output_scan_number) {
       /* If input is working on current scan, we ordinarily want it to
        * have completed the current row.  But if input scan is DC,
-       * we want it to keep one row ahead so that next block row's DC
+       * we want it to keep two rows ahead so that next two block rows' DC
        * values are up to date.
        */
-      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
+      JDIMENSION delta = (cinfo->Ss == 0) ? 2 : 0;
       if (cinfo->input_iMCU_row > cinfo->output_iMCU_row + delta)
         break;
     }
@@ -452,34 +475,53 @@
     if (!compptr->component_needed)
       continue;
     /* Count non-dummy DCT block rows in this iMCU row. */
-    if (cinfo->output_iMCU_row < last_iMCU_row) {
+    if (cinfo->output_iMCU_row < last_iMCU_row - 1) {
+      block_rows = compptr->v_samp_factor;
+      access_rows = block_rows * 3; /* this and next two iMCU rows */
+    } else if (cinfo->output_iMCU_row < last_iMCU_row) {
       block_rows = compptr->v_samp_factor;
       access_rows = block_rows * 2; /* this and next iMCU row */
-      last_row = FALSE;
     } else {
       /* NB: can't use last_row_height here; it is input-side-dependent! */
       block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor);
       if (block_rows == 0) block_rows = compptr->v_samp_factor;
       access_rows = block_rows; /* this iMCU row only */
-      last_row = TRUE;
     }
     /* Align the virtual buffer for this component. */
-    if (cinfo->output_iMCU_row > 0) {
-      access_rows += compptr->v_samp_factor; /* prior iMCU row too */
+    if (cinfo->output_iMCU_row > 1) {
+      access_rows += 2 * compptr->v_samp_factor; /* prior two iMCU rows too */
+      buffer = (*cinfo->mem->access_virt_barray)
+        ((j_common_ptr)cinfo, coef->whole_image[ci],
+         (cinfo->output_iMCU_row - 2) * compptr->v_samp_factor,
+         (JDIMENSION)access_rows, FALSE);
+      buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */
+    } else if (cinfo->output_iMCU_row > 0) {
       buffer = (*cinfo->mem->access_virt_barray)
         ((j_common_ptr)cinfo, coef->whole_image[ci],
          (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
          (JDIMENSION)access_rows, FALSE);
       buffer += compptr->v_samp_factor; /* point to current iMCU row */
-      first_row = FALSE;
     } else {
       buffer = (*cinfo->mem->access_virt_barray)
         ((j_common_ptr)cinfo, coef->whole_image[ci],
          (JDIMENSION)0, (JDIMENSION)access_rows, FALSE);
-      first_row = TRUE;
     }
-    /* Fetch component-dependent info */
-    coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
+    /* Fetch component-dependent info.
+     * If the current scan is incomplete, then we use the component-dependent
+     * info from the previous scan.
+     */
+    if (cinfo->output_iMCU_row > cinfo->master->last_good_iMCU_row)
+      coef_bits =
+        coef->coef_bits_latch + ((ci + cinfo->num_components) * SAVED_COEFS);
+    else
+      coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
+
+    /* We only do DC interpolation if no AC coefficient data is available. */
+    change_dc =
+      coef_bits[1] == -1 && coef_bits[2] == -1 && coef_bits[3] == -1 &&
+      coef_bits[4] == -1 && coef_bits[5] == -1 && coef_bits[6] == -1 &&
+      coef_bits[7] == -1 && coef_bits[8] == -1 && coef_bits[9] == -1;
+
     quanttbl = compptr->quant_table;
     Q00 = quanttbl->quantval[0];
     Q01 = quanttbl->quantval[Q01_POS];
@@ -487,25 +529,51 @@
     Q20 = quanttbl->quantval[Q20_POS];
     Q11 = quanttbl->quantval[Q11_POS];
     Q02 = quanttbl->quantval[Q02_POS];
+    if (change_dc) {
+      Q03 = quanttbl->quantval[Q03_POS];
+      Q12 = quanttbl->quantval[Q12_POS];
+      Q21 = quanttbl->quantval[Q21_POS];
+      Q30 = quanttbl->quantval[Q30_POS];
+    }
     inverse_DCT = cinfo->idct->inverse_DCT[ci];
     output_ptr = output_buf[ci];
     /* Loop over all DCT blocks to be processed. */
     for (block_row = 0; block_row < block_rows; block_row++) {
       buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci];
-      if (first_row && block_row == 0)
+
+      if (block_row > 0 || cinfo->output_iMCU_row > 0)
+        prev_block_row =
+          buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
+      else
         prev_block_row = buffer_ptr;
+
+      if (block_row > 1 || cinfo->output_iMCU_row > 1)
+        prev_prev_block_row =
+          buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
       else
-        prev_block_row = buffer[block_row - 1];
-      if (last_row && block_row == block_rows - 1)
+        prev_prev_block_row = prev_block_row;
+
+      if (block_row < block_rows - 1 || cinfo->output_iMCU_row < last_iMCU_row)
+        next_block_row =
+          buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
+      else
         next_block_row = buffer_ptr;
+
+      if (block_row < block_rows - 2 ||
+          cinfo->output_iMCU_row < last_iMCU_row - 1)
+        next_next_block_row =
+          buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
       else
-        next_block_row = buffer[block_row + 1];
+        next_next_block_row = next_block_row;
+
       /* We fetch the surrounding DC values using a sliding-register approach.
-       * Initialize all nine here so as to do the right thing on narrow pics.
+       * Initialize all 25 here so as to do the right thing on narrow pics.
        */
-      DC1 = DC2 = DC3 = (int)prev_block_row[0][0];
-      DC4 = DC5 = DC6 = (int)buffer_ptr[0][0];
-      DC7 = DC8 = DC9 = (int)next_block_row[0][0];
+      DC01 = DC02 = DC03 = DC04 = DC05 = (int)prev_prev_block_row[0][0];
+      DC06 = DC07 = DC08 = DC09 = DC10 = (int)prev_block_row[0][0];
+      DC11 = DC12 = DC13 = DC14 = DC15 = (int)buffer_ptr[0][0];
+      DC16 = DC17 = DC18 = DC19 = DC20 = (int)next_block_row[0][0];
+      DC21 = DC22 = DC23 = DC24 = DC25 = (int)next_next_block_row[0][0];
       output_col = 0;
       last_block_column = compptr->width_in_blocks - 1;
       for (block_num = cinfo->master->first_MCU_col[ci];
@@ -513,18 +581,39 @@
         /* Fetch current DCT block into workspace so we can modify it. */
         jcopy_block_row(buffer_ptr, (JBLOCKROW)workspace, (JDIMENSION)1);
         /* Update DC values */
-        if (block_num < last_block_column) {
-          DC3 = (int)prev_block_row[1][0];
-          DC6 = (int)buffer_ptr[1][0];
-          DC9 = (int)next_block_row[1][0];
+        if (block_num == cinfo->master->first_MCU_col[ci] &&
+            block_num < last_block_column) {
+          DC04 = (int)prev_prev_block_row[1][0];
+          DC09 = (int)prev_block_row[1][0];
+          DC14 = (int)buffer_ptr[1][0];
+          DC19 = (int)next_block_row[1][0];
+          DC24 = (int)next_next_block_row[1][0];
         }
-        /* Compute coefficient estimates per K.8.
-         * An estimate is applied only if coefficient is still zero,
-         * and is not known to be fully accurate.
+        if (block_num + 1 < last_block_column) {
+          DC05 = (int)prev_prev_block_row[2][0];
+          DC10 = (int)prev_block_row[2][0];
+          DC15 = (int)buffer_ptr[2][0];
+          DC20 = (int)next_block_row[2][0];
+          DC25 = (int)next_next_block_row[2][0];
+        }
+        /* If DC interpolation is enabled, compute coefficient estimates using
+         * a Gaussian-like kernel, keeping the averages of the DC values.
+         *
+         * If DC interpolation is disabled, compute coefficient estimates using
+         * an algorithm similar to the one described in Section K.8 of the JPEG
+         * standard, except applied to a 5x5 window rather than a 3x3 window.
+         *
+         * An estimate is applied only if the coefficient is still zero and is
+         * not known to be fully accurate.
          */
         /* AC01 */
         if ((Al = coef_bits[1]) != 0 && workspace[1] == 0) {
-          num = 36 * Q00 * (DC4 - DC6);
+          num = Q00 * (change_dc ?
+                (-DC01 - DC02 + DC04 + DC05 - 3 * DC06 + 13 * DC07 -
+                 13 * DC09 + 3 * DC10 - 3 * DC11 + 38 * DC12 - 38 * DC14 +
+                 3 * DC15 - 3 * DC16 + 13 * DC17 - 13 * DC19 + 3 * DC20 -
+                 DC21 - DC22 + DC24 + DC25) :
+                (-7 * DC11 + 50 * DC12 - 50 * DC14 + 7 * DC15));
           if (num >= 0) {
             pred = (int)(((Q01 << 7) + num) / (Q01 << 8));
             if (Al > 0 && pred >= (1 << Al))
@@ -539,7 +628,12 @@
         }
         /* AC10 */
         if ((Al = coef_bits[2]) != 0 && workspace[8] == 0) {
-          num = 36 * Q00 * (DC2 - DC8);
+          num = Q00 * (change_dc ?
+                (-DC01 - 3 * DC02 - 3 * DC03 - 3 * DC04 - DC05 - DC06 +
+                 13 * DC07 + 38 * DC08 + 13 * DC09 - DC10 + DC16 -
+                 13 * DC17 - 38 * DC18 - 13 * DC19 + DC20 + DC21 +
+                 3 * DC22 + 3 * DC23 + 3 * DC24 + DC25) :
+                (-7 * DC03 + 50 * DC08 - 50 * DC18 + 7 * DC23));
           if (num >= 0) {
             pred = (int)(((Q10 << 7) + num) / (Q10 << 8));
             if (Al > 0 && pred >= (1 << Al))
@@ -554,7 +648,10 @@
         }
         /* AC20 */
         if ((Al = coef_bits[3]) != 0 && workspace[16] == 0) {
-          num = 9 * Q00 * (DC2 + DC8 - 2 * DC5);
+          num = Q00 * (change_dc ?
+                (DC03 + 2 * DC07 + 7 * DC08 + 2 * DC09 - 5 * DC12 - 14 * DC13 -
+                 5 * DC14 + 2 * DC17 + 7 * DC18 + 2 * DC19 + DC23) :
+                (-DC03 + 13 * DC08 - 24 * DC13 + 13 * DC18 - DC23));
           if (num >= 0) {
             pred = (int)(((Q20 << 7) + num) / (Q20 << 8));
             if (Al > 0 && pred >= (1 << Al))
@@ -569,7 +666,11 @@
         }
         /* AC11 */
         if ((Al = coef_bits[4]) != 0 && workspace[9] == 0) {
-          num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
+          num = Q00 * (change_dc ?
+                (-DC01 + DC05 + 9 * DC07 - 9 * DC09 - 9 * DC17 +
+                 9 * DC19 + DC21 - DC25) :
+                (DC10 + DC16 - 10 * DC17 + 10 * DC19 - DC02 - DC20 + DC22 -
+                 DC24 + DC04 - DC06 + 10 * DC07 - 10 * DC09));
           if (num >= 0) {
             pred = (int)(((Q11 << 7) + num) / (Q11 << 8));
             if (Al > 0 && pred >= (1 << Al))
@@ -584,7 +685,10 @@
         }
         /* AC02 */
         if ((Al = coef_bits[5]) != 0 && workspace[2] == 0) {
-          num = 9 * Q00 * (DC4 + DC6 - 2 * DC5);
+          num = Q00 * (change_dc ?
+                (2 * DC07 - 5 * DC08 + 2 * DC09 + DC11 + 7 * DC12 - 14 * DC13 +
+                 7 * DC14 + DC15 + 2 * DC17 - 5 * DC18 + 2 * DC19) :
+                (-DC11 + 13 * DC12 - 24 * DC13 + 13 * DC14 - DC15));
           if (num >= 0) {
             pred = (int)(((Q02 << 7) + num) / (Q02 << 8));
             if (Al > 0 && pred >= (1 << Al))
@@ -597,14 +701,96 @@
           }
           workspace[2] = (JCOEF)pred;
         }
+        if (change_dc) {
+          /* AC03 */
+          if ((Al = coef_bits[6]) != 0 && workspace[3] == 0) {
+            num = Q00 * (DC07 - DC09 + 2 * DC12 - 2 * DC14 + DC17 - DC19);
+            if (num >= 0) {
+              pred = (int)(((Q03 << 7) + num) / (Q03 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+            } else {
+              pred = (int)(((Q03 << 7) - num) / (Q03 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+              pred = -pred;
+            }
+            workspace[3] = (JCOEF)pred;
+          }
+          /* AC12 */
+          if ((Al = coef_bits[7]) != 0 && workspace[10] == 0) {
+            num = Q00 * (DC07 - 3 * DC08 + DC09 - DC17 + 3 * DC18 - DC19);
+            if (num >= 0) {
+              pred = (int)(((Q12 << 7) + num) / (Q12 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+            } else {
+              pred = (int)(((Q12 << 7) - num) / (Q12 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+              pred = -pred;
+            }
+            workspace[10] = (JCOEF)pred;
+          }
+          /* AC21 */
+          if ((Al = coef_bits[8]) != 0 && workspace[17] == 0) {
+            num = Q00 * (DC07 - DC09 - 3 * DC12 + 3 * DC14 + DC17 - DC19);
+            if (num >= 0) {
+              pred = (int)(((Q21 << 7) + num) / (Q21 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+            } else {
+              pred = (int)(((Q21 << 7) - num) / (Q21 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+              pred = -pred;
+            }
+            workspace[17] = (JCOEF)pred;
+          }
+          /* AC30 */
+          if ((Al = coef_bits[9]) != 0 && workspace[24] == 0) {
+            num = Q00 * (DC07 + 2 * DC08 + DC09 - DC17 - 2 * DC18 - DC19);
+            if (num >= 0) {
+              pred = (int)(((Q30 << 7) + num) / (Q30 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+            } else {
+              pred = (int)(((Q30 << 7) - num) / (Q30 << 8));
+              if (Al > 0 && pred >= (1 << Al))
+                pred = (1 << Al) - 1;
+              pred = -pred;
+            }
+            workspace[24] = (JCOEF)pred;
+          }
+          /* coef_bits[0] is non-negative.  Otherwise this function would not
+           * be called.
+           */
+          num = Q00 *
+                (-2 * DC01 - 6 * DC02 - 8 * DC03 - 6 * DC04 - 2 * DC05 -
+                 6 * DC06 + 6 * DC07 + 42 * DC08 + 6 * DC09 - 6 * DC10 -
+                 8 * DC11 + 42 * DC12 + 152 * DC13 + 42 * DC14 - 8 * DC15 -
+                 6 * DC16 + 6 * DC17 + 42 * DC18 + 6 * DC19 - 6 * DC20 -
+                 2 * DC21 - 6 * DC22 - 8 * DC23 - 6 * DC24 - 2 * DC25);
+          if (num >= 0) {
+            pred = (int)(((Q00 << 7) + num) / (Q00 << 8));
+          } else {
+            pred = (int)(((Q00 << 7) - num) / (Q00 << 8));
+            pred = -pred;
+          }
+          workspace[0] = (JCOEF)pred;
+        }  /* change_dc */
+
         /* OK, do the IDCT */
         (*inverse_DCT) (cinfo, compptr, (JCOEFPTR)workspace, output_ptr,
                         output_col);
         /* Advance for next column */
-        DC1 = DC2;  DC2 = DC3;
-        DC4 = DC5;  DC5 = DC6;
-        DC7 = DC8;  DC8 = DC9;
-        buffer_ptr++, prev_block_row++, next_block_row++;
+        DC01 = DC02;  DC02 = DC03;  DC03 = DC04;  DC04 = DC05;
+        DC06 = DC07;  DC07 = DC08;  DC08 = DC09;  DC09 = DC10;
+        DC11 = DC12;  DC12 = DC13;  DC13 = DC14;  DC14 = DC15;
+        DC16 = DC17;  DC17 = DC18;  DC18 = DC19;  DC19 = DC20;
+        DC21 = DC22;  DC22 = DC23;  DC23 = DC24;  DC24 = DC25;
+        buffer_ptr++, prev_block_row++, next_block_row++,
+          prev_prev_block_row++, next_next_block_row++;
         output_col += compptr->_DCT_scaled_size;
       }
       output_ptr += compptr->_DCT_scaled_size;
@@ -653,7 +839,7 @@
 #ifdef BLOCK_SMOOTHING_SUPPORTED
       /* If block smoothing could be used, need a bigger window */
       if (cinfo->progressive_mode)
-        access_rows *= 3;
+        access_rows *= 5;
 #endif
       coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
         ((j_common_ptr)cinfo, JPOOL_IMAGE, TRUE,
diff --git a/src/third_party/libjpeg-turbo/jdcoefct.h b/src/third_party/libjpeg-turbo/jdcoefct.h
index c4d1943..9a0e780 100644
--- a/src/third_party/libjpeg-turbo/jdcoefct.h
+++ b/src/third_party/libjpeg-turbo/jdcoefct.h
@@ -5,6 +5,7 @@
  * Copyright (C) 1994-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2020, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  */
@@ -51,7 +52,7 @@
 #ifdef BLOCK_SMOOTHING_SUPPORTED
   /* When doing block smoothing, we latch coefficient Al values here */
   int *coef_bits_latch;
-#define SAVED_COEFS  6          /* we save coef_bits[0..5] */
+#define SAVED_COEFS  10         /* we save coef_bits[0..9] */
 #endif
 } my_coef_controller;
 
diff --git a/src/third_party/libjpeg-turbo/jdcol565.c b/src/third_party/libjpeg-turbo/jdcol565.c
index 40068ef..53c7bd9 100644
--- a/src/third_party/libjpeg-turbo/jdcol565.c
+++ b/src/third_party/libjpeg-turbo/jdcol565.c
@@ -45,9 +45,9 @@
     outptr = *output_buf++;
 
     if (PACK_NEED_ALIGNMENT(outptr)) {
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[y + Crrtab[cr]];
       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
                                             SCALEBITS))];
@@ -58,18 +58,18 @@
       num_cols--;
     }
     for (col = 0; col < (num_cols >> 1); col++) {
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[y + Crrtab[cr]];
       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
                                             SCALEBITS))];
       b = range_limit[y + Cbbtab[cb]];
       rgb = PACK_SHORT_565(r, g, b);
 
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[y + Crrtab[cr]];
       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
                                             SCALEBITS))];
@@ -80,9 +80,9 @@
       outptr += 4;
     }
     if (num_cols & 1) {
-      y  = GETJSAMPLE(*inptr0);
-      cb = GETJSAMPLE(*inptr1);
-      cr = GETJSAMPLE(*inptr2);
+      y  = *inptr0;
+      cb = *inptr1;
+      cr = *inptr2;
       r = range_limit[y + Crrtab[cr]];
       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
                                             SCALEBITS))];
@@ -125,9 +125,9 @@
     input_row++;
     outptr = *output_buf++;
     if (PACK_NEED_ALIGNMENT(outptr)) {
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
       g = range_limit[DITHER_565_G(y +
                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -139,9 +139,9 @@
       num_cols--;
     }
     for (col = 0; col < (num_cols >> 1); col++) {
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
       g = range_limit[DITHER_565_G(y +
                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -150,9 +150,9 @@
       d0 = DITHER_ROTATE(d0);
       rgb = PACK_SHORT_565(r, g, b);
 
-      y  = GETJSAMPLE(*inptr0++);
-      cb = GETJSAMPLE(*inptr1++);
-      cr = GETJSAMPLE(*inptr2++);
+      y  = *inptr0++;
+      cb = *inptr1++;
+      cr = *inptr2++;
       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
       g = range_limit[DITHER_565_G(y +
                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -165,9 +165,9 @@
       outptr += 4;
     }
     if (num_cols & 1) {
-      y  = GETJSAMPLE(*inptr0);
-      cb = GETJSAMPLE(*inptr1);
-      cr = GETJSAMPLE(*inptr2);
+      y  = *inptr0;
+      cb = *inptr1;
+      cr = *inptr2;
       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
       g = range_limit[DITHER_565_G(y +
                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -202,32 +202,32 @@
     input_row++;
     outptr = *output_buf++;
     if (PACK_NEED_ALIGNMENT(outptr)) {
-      r = GETJSAMPLE(*inptr0++);
-      g = GETJSAMPLE(*inptr1++);
-      b = GETJSAMPLE(*inptr2++);
+      r = *inptr0++;
+      g = *inptr1++;
+      b = *inptr2++;
       rgb = PACK_SHORT_565(r, g, b);
       *(INT16 *)outptr = (INT16)rgb;
       outptr += 2;
       num_cols--;
     }
     for (col = 0; col < (num_cols >> 1); col++) {
-      r = GETJSAMPLE(*inptr0++);
-      g = GETJSAMPLE(*inptr1++);
-      b = GETJSAMPLE(*inptr2++);
+      r = *inptr0++;
+      g = *inptr1++;
+      b = *inptr2++;
       rgb = PACK_SHORT_565(r, g, b);
 
-      r = GETJSAMPLE(*inptr0++);
-      g = GETJSAMPLE(*inptr1++);
-      b = GETJSAMPLE(*inptr2++);
+      r = *inptr0++;
+      g = *inptr1++;
+      b = *inptr2++;
       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
 
       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
       outptr += 4;
     }
     if (num_cols & 1) {
-      r = GETJSAMPLE(*inptr0);
-      g = GETJSAMPLE(*inptr1);
-      b = GETJSAMPLE(*inptr2);
+      r = *inptr0;
+      g = *inptr1;
+      b = *inptr2;
       rgb = PACK_SHORT_565(r, g, b);
       *(INT16 *)outptr = (INT16)rgb;
     }
@@ -259,24 +259,24 @@
     input_row++;
     outptr = *output_buf++;
     if (PACK_NEED_ALIGNMENT(outptr)) {
-      r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
-      g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
-      b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
+      r = range_limit[DITHER_565_R(*inptr0++, d0)];
+      g = range_limit[DITHER_565_G(*inptr1++, d0)];
+      b = range_limit[DITHER_565_B(*inptr2++, d0)];
       rgb = PACK_SHORT_565(r, g, b);
       *(INT16 *)outptr = (INT16)rgb;
       outptr += 2;
       num_cols--;
     }
     for (col = 0; col < (num_cols >> 1); col++) {
-      r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
-      g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
-      b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
+      r = range_limit[DITHER_565_R(*inptr0++, d0)];
+      g = range_limit[DITHER_565_G(*inptr1++, d0)];
+      b = range_limit[DITHER_565_B(*inptr2++, d0)];
       d0 = DITHER_ROTATE(d0);
       rgb = PACK_SHORT_565(r, g, b);
 
-      r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
-      g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
-      b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
+      r = range_limit[DITHER_565_R(*inptr0++, d0)];
+      g = range_limit[DITHER_565_G(*inptr1++, d0)];
+      b = range_limit[DITHER_565_B(*inptr2++, d0)];
       d0 = DITHER_ROTATE(d0);
       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
 
@@ -284,9 +284,9 @@
       outptr += 4;
     }
     if (num_cols & 1) {
-      r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
-      g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
-      b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
+      r = range_limit[DITHER_565_R(*inptr0, d0)];
+      g = range_limit[DITHER_565_G(*inptr1, d0)];
+      b = range_limit[DITHER_565_B(*inptr2, d0)];
       rgb = PACK_SHORT_565(r, g, b);
       *(INT16 *)outptr = (INT16)rgb;
     }
diff --git a/src/third_party/libjpeg-turbo/jdcolext.c b/src/third_party/libjpeg-turbo/jdcolext.c
index 72a5301..863c7a2 100644
--- a/src/third_party/libjpeg-turbo/jdcolext.c
+++ b/src/third_party/libjpeg-turbo/jdcolext.c
@@ -53,9 +53,9 @@
     input_row++;
     outptr = *output_buf++;
     for (col = 0; col < num_cols; col++) {
-      y  = GETJSAMPLE(inptr0[col]);
-      cb = GETJSAMPLE(inptr1[col]);
-      cr = GETJSAMPLE(inptr2[col]);
+      y  = inptr0[col];
+      cb = inptr1[col];
+      cr = inptr2[col];
       /* Range-limiting is essential due to noise introduced by DCT losses. */
       outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
       outptr[RGB_GREEN] = range_limit[y +
@@ -93,7 +93,6 @@
     inptr = input_buf[0][input_row++];
     outptr = *output_buf++;
     for (col = 0; col < num_cols; col++) {
-      /* We can dispense with GETJSAMPLE() here */
       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
       /* alpha channel value */
@@ -128,7 +127,6 @@
     input_row++;
     outptr = *output_buf++;
     for (col = 0; col < num_cols; col++) {
-      /* We can dispense with GETJSAMPLE() here */
       outptr[RGB_RED] = inptr0[col];
       outptr[RGB_GREEN] = inptr1[col];
       outptr[RGB_BLUE] = inptr2[col];
diff --git a/src/third_party/libjpeg-turbo/jdcolor.c b/src/third_party/libjpeg-turbo/jdcolor.c
index fd7f661..8da2b4e 100644
--- a/src/third_party/libjpeg-turbo/jdcolor.c
+++ b/src/third_party/libjpeg-turbo/jdcolor.c
@@ -341,9 +341,9 @@
     input_row++;
     outptr = *output_buf++;
     for (col = 0; col < num_cols; col++) {
-      r = GETJSAMPLE(inptr0[col]);
-      g = GETJSAMPLE(inptr1[col]);
-      b = GETJSAMPLE(inptr2[col]);
+      r = inptr0[col];
+      g = inptr1[col];
+      b = inptr2[col];
       /* Y */
       outptr[col] = (JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
                                ctab[b + B_Y_OFF]) >> SCALEBITS);
@@ -550,9 +550,9 @@
     input_row++;
     outptr = *output_buf++;
     for (col = 0; col < num_cols; col++) {
-      y  = GETJSAMPLE(inptr0[col]);
-      cb = GETJSAMPLE(inptr1[col]);
-      cr = GETJSAMPLE(inptr2[col]);
+      y  = inptr0[col];
+      cb = inptr1[col];
+      cr = inptr2[col];
       /* Range-limiting is essential due to noise introduced by DCT losses. */
       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
@@ -560,7 +560,7 @@
                                                  SCALEBITS)))];
       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
       /* K passes through unchanged */
-      outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
+      outptr[3] = inptr3[col];
       outptr += 4;
     }
   }
@@ -571,11 +571,10 @@
  * RGB565 conversion
  */
 
-#define PACK_SHORT_565_LE(r, g, b)  ((((r) << 8) & 0xF800) | \
-                                     (((g) << 3) & 0x7E0) | ((b) >> 3))
-#define PACK_SHORT_565_BE(r, g, b)  (((r) & 0xF8) | ((g) >> 5) | \
-                                     (((g) << 11) & 0xE000) | \
-                                     (((b) << 5) & 0x1F00))
+#define PACK_SHORT_565_LE(r, g, b) \
+  ((((r) << 8) & 0xF800) | (((g) << 3) & 0x7E0) | ((b) >> 3))
+#define PACK_SHORT_565_BE(r, g, b) \
+  (((r) & 0xF8) | ((g) >> 5) | (((g) << 11) & 0xE000) | (((b) << 5) & 0x1F00))
 
 #define PACK_TWO_PIXELS_LE(l, r)    ((r << 16) | l)
 #define PACK_TWO_PIXELS_BE(l, r)    ((l << 16) | r)
@@ -592,7 +591,7 @@
 /* Declarations for ordered dithering
  *
  * We use a 4x4 ordered dither array packed into 32 bits.  This array is
- * sufficent for dithering RGB888 to RGB565.
+ * sufficient for dithering RGB888 to RGB565.
  */
 
 #define DITHER_MASK       0x3
diff --git a/src/third_party/libjpeg-turbo/jdhuff.c b/src/third_party/libjpeg-turbo/jdhuff.c
index 84b9b71..f786c10 100644
--- a/src/third_party/libjpeg-turbo/jdhuff.c
+++ b/src/third_party/libjpeg-turbo/jdhuff.c
@@ -4,7 +4,8 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009-2011, 2016, D. R. Commander.
+ * Copyright (C) 2009-2011, 2016, 2018-2019, D. R. Commander.
+ * Copyright (C) 2018, Matthias Räncker.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -15,6 +16,9 @@
  * up to the start of the current MCU.  To do this, we copy state variables
  * into local working storage, and update them back to the permanent
  * storage only upon successful completion of an MCU.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  */
 
 #define JPEG_INTERNALS
@@ -36,24 +40,6 @@
   int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
 } savable_state;
 
-/* This macro is to work around compilers with missing or broken
- * structure assignment.  You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
-#ifndef NO_STRUCT_ASSIGN
-#define ASSIGN_STATE(dest, src)  ((dest) = (src))
-#else
-#if MAX_COMPS_IN_SCAN == 4
-#define ASSIGN_STATE(dest, src) \
-  ((dest).last_dc_val[0] = (src).last_dc_val[0], \
-   (dest).last_dc_val[1] = (src).last_dc_val[1], \
-   (dest).last_dc_val[2] = (src).last_dc_val[2], \
-   (dest).last_dc_val[3] = (src).last_dc_val[3])
-#endif
-#endif
-
-
 typedef struct {
   struct jpeg_entropy_decoder pub; /* public fields */
 
@@ -322,7 +308,7 @@
         bytes_in_buffer = cinfo->src->bytes_in_buffer;
       }
       bytes_in_buffer--;
-      c = GETJOCTET(*next_input_byte++);
+      c = *next_input_byte++;
 
       /* If it's 0xFF, check and discard stuffed zero byte */
       if (c == 0xFF) {
@@ -339,7 +325,7 @@
             bytes_in_buffer = cinfo->src->bytes_in_buffer;
           }
           bytes_in_buffer--;
-          c = GETJOCTET(*next_input_byte++);
+          c = *next_input_byte++;
         } while (c == 0xFF);
 
         if (c == 0) {
@@ -402,8 +388,8 @@
 
 #define GET_BYTE { \
   register int c0, c1; \
-  c0 = GETJOCTET(*buffer++); \
-  c1 = GETJOCTET(*buffer); \
+  c0 = *buffer++; \
+  c1 = *buffer; \
   /* Pre-execute most common case */ \
   get_buffer = (get_buffer << 8) | c0; \
   bits_left += 8; \
@@ -420,7 +406,7 @@
   } \
 }
 
-#if SIZEOF_SIZE_T == 8 || defined(_WIN64)
+#if SIZEOF_SIZE_T == 8 || defined(_WIN64) || (defined(__x86_64__) && defined(__ILP32__))
 
 /* Pre-fetch 48 bytes, because the holding register is 64-bit */
 #define FILL_BIT_BUFFER_FAST \
@@ -459,7 +445,7 @@
   code = GET_BITS(l);
 
   /* Collect the rest of the Huffman code one bit at a time. */
-  /* This is per Figure F.16 in the JPEG spec. */
+  /* This is per Figure F.16. */
 
   while (code > htbl->maxcode[l]) {
     code <<= 1;
@@ -554,6 +540,12 @@
 }
 
 
+#if defined(__has_feature)
+#if __has_feature(undefined_behavior_sanitizer)
+__attribute__((no_sanitize("signed-integer-overflow"),
+               no_sanitize("unsigned-integer-overflow")))
+#endif
+#endif
 LOCAL(boolean)
 decode_mcu_slow(j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 {
@@ -565,7 +557,7 @@
 
   /* Load up working state */
   BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
-  ASSIGN_STATE(state, entropy->saved);
+  state = entropy->saved;
 
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
     JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
@@ -586,6 +578,14 @@
     if (entropy->dc_needed[blkn]) {
       /* Convert DC difference to actual value, update last_dc_val */
       int ci = cinfo->MCU_membership[blkn];
+      /* Certain malformed JPEG images produce repeated DC coefficient
+       * differences of 2047 or -2047, which causes state.last_dc_val[ci] to
+       * grow until it overflows or underflows a 32-bit signed integer.  This
+       * behavior is, to the best of our understanding, innocuous, and it is
+       * unclear how to work around it without potentially affecting
+       * performance.  Thus, we (hopefully temporarily) suppress UBSan integer
+       * overflow errors for this function.
+       */
       s += state.last_dc_val[ci];
       state.last_dc_val[ci] = s;
       if (block) {
@@ -646,7 +646,7 @@
 
   /* Completed MCU, so update state */
   BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
-  ASSIGN_STATE(entropy->saved, state);
+  entropy->saved = state;
   return TRUE;
 }
 
@@ -664,7 +664,7 @@
   /* Load up working state */
   BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
   buffer = (JOCTET *)br_state.next_input_byte;
-  ASSIGN_STATE(state, entropy->saved);
+  state = entropy->saved;
 
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
     JBLOCKROW block = MCU_data ? MCU_data[blkn] : NULL;
@@ -733,7 +733,7 @@
   br_state.bytes_in_buffer -= (buffer - br_state.next_input_byte);
   br_state.next_input_byte = buffer;
   BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
-  ASSIGN_STATE(entropy->saved, state);
+  entropy->saved = state;
   return TRUE;
 }
 
@@ -788,7 +788,8 @@
   }
 
   /* Account for restart interval (no-op if not using restarts) */
-  entropy->restarts_to_go--;
+  if (cinfo->restart_interval)
+    entropy->restarts_to_go--;
 
   return TRUE;
 }
diff --git a/src/third_party/libjpeg-turbo/jdhuff.h b/src/third_party/libjpeg-turbo/jdhuff.h
index 6a8d90f..cfa0b7f 100644
--- a/src/third_party/libjpeg-turbo/jdhuff.h
+++ b/src/third_party/libjpeg-turbo/jdhuff.h
@@ -4,7 +4,8 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010-2011, 2015-2016, D. R. Commander.
+ * Copyright (C) 2010-2011, 2015-2016, 2021, D. R. Commander.
+ * Copyright (C) 2018, Matthias Räncker.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -78,6 +79,11 @@
 typedef size_t bit_buf_type;            /* type of bit-extraction buffer */
 #define BIT_BUF_SIZE  64                /* size of buffer in bits */
 
+#elif defined(__x86_64__) && defined(__ILP32__)
+
+typedef unsigned long long bit_buf_type; /* type of bit-extraction buffer */
+#define BIT_BUF_SIZE  64                 /* size of buffer in bits */
+
 #else
 
 typedef unsigned long bit_buf_type;     /* type of bit-extraction buffer */
@@ -228,7 +234,10 @@
       s |= GET_BITS(1); \
       nb++; \
     } \
-    s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
+    if (nb > 16) \
+      s = 0; \
+    else \
+      s = htbl->pub->huffval[(int)(s + htbl->valoffset[nb]) & 0xFF]; \
   }
 
 /* Out-of-line case for Huffman code fetching */
diff --git a/src/third_party/libjpeg-turbo/jdicc.c b/src/third_party/libjpeg-turbo/jdicc.c
index 7224695..a1a5b86 100644
--- a/src/third_party/libjpeg-turbo/jdicc.c
+++ b/src/third_party/libjpeg-turbo/jdicc.c
@@ -38,18 +38,18 @@
     marker->marker == ICC_MARKER &&
     marker->data_length >= ICC_OVERHEAD_LEN &&
     /* verify the identifying string */
-    GETJOCTET(marker->data[0]) == 0x49 &&
-    GETJOCTET(marker->data[1]) == 0x43 &&
-    GETJOCTET(marker->data[2]) == 0x43 &&
-    GETJOCTET(marker->data[3]) == 0x5F &&
-    GETJOCTET(marker->data[4]) == 0x50 &&
-    GETJOCTET(marker->data[5]) == 0x52 &&
-    GETJOCTET(marker->data[6]) == 0x4F &&
-    GETJOCTET(marker->data[7]) == 0x46 &&
-    GETJOCTET(marker->data[8]) == 0x49 &&
-    GETJOCTET(marker->data[9]) == 0x4C &&
-    GETJOCTET(marker->data[10]) == 0x45 &&
-    GETJOCTET(marker->data[11]) == 0x0;
+    marker->data[0] == 0x49 &&
+    marker->data[1] == 0x43 &&
+    marker->data[2] == 0x43 &&
+    marker->data[3] == 0x5F &&
+    marker->data[4] == 0x50 &&
+    marker->data[5] == 0x52 &&
+    marker->data[6] == 0x4F &&
+    marker->data[7] == 0x46 &&
+    marker->data[8] == 0x49 &&
+    marker->data[9] == 0x4C &&
+    marker->data[10] == 0x45 &&
+    marker->data[11] == 0x0;
 }
 
 
@@ -102,12 +102,12 @@
   for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
     if (marker_is_icc(marker)) {
       if (num_markers == 0)
-        num_markers = GETJOCTET(marker->data[13]);
-      else if (num_markers != GETJOCTET(marker->data[13])) {
+        num_markers = marker->data[13];
+      else if (num_markers != marker->data[13]) {
         WARNMS(cinfo, JWRN_BOGUS_ICC);  /* inconsistent num_markers fields */
         return FALSE;
       }
-      seq_no = GETJOCTET(marker->data[12]);
+      seq_no = marker->data[12];
       if (seq_no <= 0 || seq_no > num_markers) {
         WARNMS(cinfo, JWRN_BOGUS_ICC);  /* bogus sequence number */
         return FALSE;
@@ -154,7 +154,7 @@
       JOCTET FAR *src_ptr;
       JOCTET *dst_ptr;
       unsigned int length;
-      seq_no = GETJOCTET(marker->data[12]);
+      seq_no = marker->data[12];
       dst_ptr = icc_data + data_offset[seq_no];
       src_ptr = marker->data + ICC_OVERHEAD_LEN;
       length = data_length[seq_no];
diff --git a/src/third_party/libjpeg-turbo/jdinput.c b/src/third_party/libjpeg-turbo/jdinput.c
index fbf8b29..deec618 100644
--- a/src/third_party/libjpeg-turbo/jdinput.c
+++ b/src/third_party/libjpeg-turbo/jdinput.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2016, D. R. Commander.
+ * Copyright (C) 2010, 2016, 2018, D. R. Commander.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -234,10 +234,10 @@
  * means that we have to save away the table actually used for each component.
  * We do this by copying the table at the start of the first scan containing
  * the component.
- * The JPEG spec prohibits the encoder from changing the contents of a Q-table
- * slot between scans of a component using that slot.  If the encoder does so
- * anyway, this decoder will simply use the Q-table values that were current
- * at the start of the first scan for the component.
+ * Rec. ITU-T T.81 | ISO/IEC 10918-1 prohibits the encoder from changing the
+ * contents of a Q-table slot between scans of a component using that slot.  If
+ * the encoder does so anyway, this decoder will simply use the Q-table values
+ * that were current at the start of the first scan for the component.
  *
  * The decompressor output side looks only at the saved quant tables,
  * not at the current Q-table slots.
diff --git a/src/third_party/libjpeg-turbo/jdmainct.c b/src/third_party/libjpeg-turbo/jdmainct.c
index 50301d6..f466b25 100644
--- a/src/third_party/libjpeg-turbo/jdmainct.c
+++ b/src/third_party/libjpeg-turbo/jdmainct.c
@@ -18,6 +18,7 @@
 
 #include "jinclude.h"
 #include "jdmainct.h"
+#include "jconfigint.h"
 
 
 /*
@@ -360,7 +361,7 @@
     main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
     if (*out_row_ctr >= out_rows_avail)
       return;                   /* Postprocessor exactly filled output buf */
-    /*FALLTHROUGH*/
+    FALLTHROUGH                 /*FALLTHROUGH*/
   case CTX_PREPARE_FOR_IMCU:
     /* Prepare to process first M-1 row groups of this iMCU row */
     main_ptr->rowgroup_ctr = 0;
@@ -371,7 +372,7 @@
     if (main_ptr->iMCU_row_ctr == cinfo->total_iMCU_rows)
       set_bottom_pointers(cinfo);
     main_ptr->context_state = CTX_PROCESS_IMCU;
-    /*FALLTHROUGH*/
+    FALLTHROUGH                 /*FALLTHROUGH*/
   case CTX_PROCESS_IMCU:
     /* Call postprocessor using previously set pointers */
     (*cinfo->post->post_process_data) (cinfo,
diff --git a/src/third_party/libjpeg-turbo/jdmarker.c b/src/third_party/libjpeg-turbo/jdmarker.c
index c9c7ef6..b964c3a 100644
--- a/src/third_party/libjpeg-turbo/jdmarker.c
+++ b/src/third_party/libjpeg-turbo/jdmarker.c
@@ -151,7 +151,7 @@
 #define INPUT_BYTE(cinfo, V, action) \
   MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
             bytes_in_buffer--; \
-            V = GETJOCTET(*next_input_byte++); )
+            V = *next_input_byte++; )
 
 /* As above, but read two bytes interpreted as an unsigned 16-bit integer.
  * V should be declared unsigned int or perhaps JLONG.
@@ -159,10 +159,10 @@
 #define INPUT_2BYTES(cinfo, V, action) \
   MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
             bytes_in_buffer--; \
-            V = ((unsigned int)GETJOCTET(*next_input_byte++)) << 8; \
+            V = ((unsigned int)(*next_input_byte++)) << 8; \
             MAKE_BYTE_AVAIL(cinfo, action); \
             bytes_in_buffer--; \
-            V += GETJOCTET(*next_input_byte++); )
+            V += *next_input_byte++; )
 
 
 /*
@@ -608,18 +608,18 @@
   JLONG totallen = (JLONG)datalen + remaining;
 
   if (datalen >= APP0_DATA_LEN &&
-      GETJOCTET(data[0]) == 0x4A &&
-      GETJOCTET(data[1]) == 0x46 &&
-      GETJOCTET(data[2]) == 0x49 &&
-      GETJOCTET(data[3]) == 0x46 &&
-      GETJOCTET(data[4]) == 0) {
+      data[0] == 0x4A &&
+      data[1] == 0x46 &&
+      data[2] == 0x49 &&
+      data[3] == 0x46 &&
+      data[4] == 0) {
     /* Found JFIF APP0 marker: save info */
     cinfo->saw_JFIF_marker = TRUE;
-    cinfo->JFIF_major_version = GETJOCTET(data[5]);
-    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
-    cinfo->density_unit = GETJOCTET(data[7]);
-    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
-    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
+    cinfo->JFIF_major_version = data[5];
+    cinfo->JFIF_minor_version = data[6];
+    cinfo->density_unit = data[7];
+    cinfo->X_density = (data[8] << 8) + data[9];
+    cinfo->Y_density = (data[10] << 8) + data[11];
     /* Check version.
      * Major version must be 1, anything else signals an incompatible change.
      * (We used to treat this as an error, but now it's a nonfatal warning,
@@ -634,24 +634,22 @@
              cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
              cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
     /* Validate thumbnail dimensions and issue appropriate messages */
-    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
-      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
-               GETJOCTET(data[12]), GETJOCTET(data[13]));
+    if (data[12] | data[13])
+      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]);
     totallen -= APP0_DATA_LEN;
-    if (totallen !=
-        ((JLONG)GETJOCTET(data[12]) * (JLONG)GETJOCTET(data[13]) * (JLONG)3))
+    if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3))
       TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen);
   } else if (datalen >= 6 &&
-             GETJOCTET(data[0]) == 0x4A &&
-             GETJOCTET(data[1]) == 0x46 &&
-             GETJOCTET(data[2]) == 0x58 &&
-             GETJOCTET(data[3]) == 0x58 &&
-             GETJOCTET(data[4]) == 0) {
+             data[0] == 0x4A &&
+             data[1] == 0x46 &&
+             data[2] == 0x58 &&
+             data[3] == 0x58 &&
+             data[4] == 0) {
     /* Found JFIF "JFXX" extension APP0 marker */
     /* The library doesn't actually do anything with these,
      * but we try to produce a helpful trace message.
      */
-    switch (GETJOCTET(data[5])) {
+    switch (data[5]) {
     case 0x10:
       TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen);
       break;
@@ -662,8 +660,7 @@
       TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen);
       break;
     default:
-      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
-               GETJOCTET(data[5]), (int)totallen);
+      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen);
       break;
     }
   } else {
@@ -684,16 +681,16 @@
   unsigned int version, flags0, flags1, transform;
 
   if (datalen >= APP14_DATA_LEN &&
-      GETJOCTET(data[0]) == 0x41 &&
-      GETJOCTET(data[1]) == 0x64 &&
-      GETJOCTET(data[2]) == 0x6F &&
-      GETJOCTET(data[3]) == 0x62 &&
-      GETJOCTET(data[4]) == 0x65) {
+      data[0] == 0x41 &&
+      data[1] == 0x64 &&
+      data[2] == 0x6F &&
+      data[3] == 0x62 &&
+      data[4] == 0x65) {
     /* Found Adobe APP14 marker */
-    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
-    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
-    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
-    transform = GETJOCTET(data[11]);
+    version = (data[5] << 8) + data[6];
+    flags0 = (data[7] << 8) + data[8];
+    flags1 = (data[9] << 8) + data[10];
+    transform = data[11];
     TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
     cinfo->saw_Adobe_marker = TRUE;
     cinfo->Adobe_transform = (UINT8)transform;
diff --git a/src/third_party/libjpeg-turbo/jdmaster.c b/src/third_party/libjpeg-turbo/jdmaster.c
index b209064..cbc8774 100644
--- a/src/third_party/libjpeg-turbo/jdmaster.c
+++ b/src/third_party/libjpeg-turbo/jdmaster.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 2002-2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009-2011, 2016, D. R. Commander.
+ * Copyright (C) 2009-2011, 2016, 2019, D. R. Commander.
  * Copyright (C) 2013, Linaro Limited.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
@@ -22,7 +22,6 @@
 #include "jpeglib.h"
 #include "jpegcomp.h"
 #include "jdmaster.h"
-#include "jsimd.h"
 
 
 /*
@@ -70,17 +69,6 @@
       cinfo->comp_info[1]._DCT_scaled_size != cinfo->_min_DCT_scaled_size ||
       cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
     return FALSE;
-#ifdef WITH_SIMD
-  /* If YCbCr-to-RGB color conversion is SIMD-accelerated but merged upsampling
-     isn't, then disabling merged upsampling is likely to be faster when
-     decompressing YCbCr JPEG images. */
-  if (!jsimd_can_h2v2_merged_upsample() && !jsimd_can_h2v1_merged_upsample() &&
-      jsimd_can_ycc_rgb() && cinfo->jpeg_color_space == JCS_YCbCr &&
-      (cinfo->out_color_space == JCS_RGB ||
-       (cinfo->out_color_space >= JCS_EXT_RGB &&
-        cinfo->out_color_space <= JCS_EXT_ARGB)))
-    return FALSE;
-#endif
   /* ??? also need to test for upsample-time rescaling, when & if supported */
   return TRUE;                  /* by golly, it'll work... */
 #else
@@ -580,6 +568,7 @@
    */
   cinfo->master->first_iMCU_col = 0;
   cinfo->master->last_iMCU_col = cinfo->MCUs_per_row - 1;
+  cinfo->master->last_good_iMCU_row = 0;
 
 #ifdef D_MULTISCAN_FILES_SUPPORTED
   /* If jpeg_start_decompress will read the whole file, initialize
diff --git a/src/third_party/libjpeg-turbo/jdmerge.c b/src/third_party/libjpeg-turbo/jdmerge.c
index d67faec..3a456d6 100644
--- a/src/third_party/libjpeg-turbo/jdmerge.c
+++ b/src/third_party/libjpeg-turbo/jdmerge.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
+ * Copyright (C) 2009, 2011, 2014-2015, 2020, D. R. Commander.
  * Copyright (C) 2013, Linaro Limited.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -40,41 +40,13 @@
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
+#include "jdmerge.h"
 #include "jsimd.h"
 #include "jconfigint.h"
 
 #ifdef UPSAMPLE_MERGING_SUPPORTED
 
 
-/* Private subobject */
-
-typedef struct {
-  struct jpeg_upsampler pub;    /* public fields */
-
-  /* Pointer to routine to do actual upsampling/conversion of one row group */
-  void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                    JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
-
-  /* Private state for YCC->RGB conversion */
-  int *Cr_r_tab;                /* => table for Cr to R conversion */
-  int *Cb_b_tab;                /* => table for Cb to B conversion */
-  JLONG *Cr_g_tab;              /* => table for Cr to G conversion */
-  JLONG *Cb_g_tab;              /* => table for Cb to G conversion */
-
-  /* For 2:1 vertical sampling, we produce two output rows at a time.
-   * We need a "spare" row buffer to hold the second output row if the
-   * application provides just a one-row buffer; we also use the spare
-   * to discard the dummy last row if the image height is odd.
-   */
-  JSAMPROW spare_row;
-  boolean spare_full;           /* T if spare buffer is occupied */
-
-  JDIMENSION out_row_width;     /* samples per output row */
-  JDIMENSION rows_to_go;        /* counts rows remaining in image */
-} my_upsampler;
-
-typedef my_upsampler *my_upsample_ptr;
-
 #define SCALEBITS       16      /* speediest right-shift on some machines */
 #define ONE_HALF        ((JLONG)1 << (SCALEBITS - 1))
 #define FIX(x)          ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
@@ -189,7 +161,7 @@
 LOCAL(void)
 build_ycc_rgb_table(j_decompress_ptr cinfo)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   int i;
   JLONG x;
   SHIFT_TEMPS
@@ -232,7 +204,7 @@
 METHODDEF(void)
 start_pass_merged_upsample(j_decompress_ptr cinfo)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
 
   /* Mark the spare buffer empty */
   upsample->spare_full = FALSE;
@@ -254,7 +226,7 @@
                    JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
 /* 2:1 vertical sampling case: may need a spare row. */
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   JSAMPROW work_ptrs[2];
   JDIMENSION num_rows;          /* number of rows returned to caller */
 
@@ -305,7 +277,7 @@
                    JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
 /* 1:1 vertical sampling case: much easier, never need a spare row. */
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
 
   /* Just do the upsampling. */
   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
@@ -420,17 +392,14 @@
  * RGB565 conversion
  */
 
-#define PACK_SHORT_565_LE(r, g, b)  ((((r) << 8) & 0xF800) | \
-                                     (((g) << 3) & 0x7E0) | ((b) >> 3))
-#define PACK_SHORT_565_BE(r, g, b)  (((r) & 0xF8) | ((g) >> 5) | \
-                                     (((g) << 11) & 0xE000) | \
-                                     (((b) << 5) & 0x1F00))
+#define PACK_SHORT_565_LE(r, g, b) \
+  ((((r) << 8) & 0xF800) | (((g) << 3) & 0x7E0) | ((b) >> 3))
+#define PACK_SHORT_565_BE(r, g, b) \
+  (((r) & 0xF8) | ((g) >> 5) | (((g) << 11) & 0xE000) | (((b) << 5) & 0x1F00))
 
 #define PACK_TWO_PIXELS_LE(l, r)    ((r << 16) | l)
 #define PACK_TWO_PIXELS_BE(l, r)    ((l << 16) | r)
 
-#define PACK_NEED_ALIGNMENT(ptr)    (((size_t)(ptr)) & 3)
-
 #define WRITE_TWO_PIXELS_LE(addr, pixels) { \
   ((INT16 *)(addr))[0] = (INT16)(pixels); \
   ((INT16 *)(addr))[1] = (INT16)((pixels) >> 16); \
@@ -448,7 +417,7 @@
 /* Declarations for ordered dithering
  *
  * We use a 4x4 ordered dither array packed into 32 bits.  This array is
- * sufficent for dithering RGB888 to RGB565.
+ * sufficient for dithering RGB888 to RGB565.
  */
 
 #define DITHER_MASK       0x3
@@ -568,11 +537,11 @@
 GLOBAL(void)
 jinit_merged_upsampler(j_decompress_ptr cinfo)
 {
-  my_upsample_ptr upsample;
+  my_merged_upsample_ptr upsample;
 
-  upsample = (my_upsample_ptr)
+  upsample = (my_merged_upsample_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                sizeof(my_upsampler));
+                                sizeof(my_merged_upsampler));
   cinfo->upsample = (struct jpeg_upsampler *)upsample;
   upsample->pub.start_pass = start_pass_merged_upsample;
   upsample->pub.need_context_rows = FALSE;
diff --git a/src/third_party/libjpeg-turbo/jdmerge.h b/src/third_party/libjpeg-turbo/jdmerge.h
new file mode 100644
index 0000000..b583396
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/jdmerge.h
@@ -0,0 +1,47 @@
+/*
+ * jdmerge.h
+ *
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2020, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ */
+
+#define JPEG_INTERNALS
+#include "jpeglib.h"
+
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+
+
+/* Private subobject */
+
+typedef struct {
+  struct jpeg_upsampler pub;    /* public fields */
+
+  /* Pointer to routine to do actual upsampling/conversion of one row group */
+  void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+                    JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
+
+  /* Private state for YCC->RGB conversion */
+  int *Cr_r_tab;                /* => table for Cr to R conversion */
+  int *Cb_b_tab;                /* => table for Cb to B conversion */
+  JLONG *Cr_g_tab;              /* => table for Cr to G conversion */
+  JLONG *Cb_g_tab;              /* => table for Cb to G conversion */
+
+  /* For 2:1 vertical sampling, we produce two output rows at a time.
+   * We need a "spare" row buffer to hold the second output row if the
+   * application provides just a one-row buffer; we also use the spare
+   * to discard the dummy last row if the image height is odd.
+   */
+  JSAMPROW spare_row;
+  boolean spare_full;           /* T if spare buffer is occupied */
+
+  JDIMENSION out_row_width;     /* samples per output row */
+  JDIMENSION rows_to_go;        /* counts rows remaining in image */
+} my_merged_upsampler;
+
+typedef my_merged_upsampler *my_merged_upsample_ptr;
+
+#endif /* UPSAMPLE_MERGING_SUPPORTED */
diff --git a/src/third_party/libjpeg-turbo/jdmrg565.c b/src/third_party/libjpeg-turbo/jdmrg565.c
index 1b87e37..980a4e2 100644
--- a/src/third_party/libjpeg-turbo/jdmrg565.c
+++ b/src/third_party/libjpeg-turbo/jdmrg565.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2013, Linaro Limited.
- * Copyright (C) 2014-2015, 2018, D. R. Commander.
+ * Copyright (C) 2014-2015, 2018, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -19,7 +19,7 @@
                                   JDIMENSION in_row_group_ctr,
                                   JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr;
@@ -43,20 +43,20 @@
   /* Loop for each pair of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
     /* Fetch 2 Y values and emit 2 pixels */
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
@@ -68,12 +68,12 @@
 
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
-    y  = GETJSAMPLE(*inptr0);
+    y  = *inptr0;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
@@ -90,7 +90,7 @@
                                    JDIMENSION in_row_group_ctr,
                                    JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr;
@@ -115,21 +115,21 @@
   /* Loop for each pair of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
     /* Fetch 2 Y values and emit 2 pixels */
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
     d0 = DITHER_ROTATE(d0);
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -142,12 +142,12 @@
 
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
-    y  = GETJSAMPLE(*inptr0);
+    y  = *inptr0;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -163,7 +163,7 @@
                                   JDIMENSION in_row_group_ctr,
                                   JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr0, outptr1;
@@ -189,20 +189,20 @@
   /* Loop for each group of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
     /* Fetch 4 Y values and emit 4 pixels */
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
@@ -211,13 +211,13 @@
     WRITE_TWO_PIXELS(outptr0, rgb);
     outptr0 += 4;
 
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
@@ -229,20 +229,20 @@
 
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
-    y  = GETJSAMPLE(*inptr00);
+    y  = *inptr00;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
     rgb = PACK_SHORT_565(r, g, b);
     *(INT16 *)outptr0 = (INT16)rgb;
 
-    y  = GETJSAMPLE(*inptr01);
+    y  = *inptr01;
     r = range_limit[y + cred];
     g = range_limit[y + cgreen];
     b = range_limit[y + cblue];
@@ -259,7 +259,7 @@
                                    JDIMENSION in_row_group_ctr,
                                    JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr0, outptr1;
@@ -287,21 +287,21 @@
   /* Loop for each group of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
     /* Fetch 4 Y values and emit 4 pixels */
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
     d0 = DITHER_ROTATE(d0);
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
@@ -311,14 +311,14 @@
     WRITE_TWO_PIXELS(outptr0, rgb);
     outptr0 += 4;
 
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     r = range_limit[DITHER_565_R(y + cred, d1)];
     g = range_limit[DITHER_565_G(y + cgreen, d1)];
     b = range_limit[DITHER_565_B(y + cblue, d1)];
     d1 = DITHER_ROTATE(d1);
     rgb = PACK_SHORT_565(r, g, b);
 
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     r = range_limit[DITHER_565_R(y + cred, d1)];
     g = range_limit[DITHER_565_G(y + cgreen, d1)];
     b = range_limit[DITHER_565_B(y + cblue, d1)];
@@ -331,20 +331,20 @@
 
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
 
-    y  = GETJSAMPLE(*inptr00);
+    y  = *inptr00;
     r = range_limit[DITHER_565_R(y + cred, d0)];
     g = range_limit[DITHER_565_G(y + cgreen, d0)];
     b = range_limit[DITHER_565_B(y + cblue, d0)];
     rgb = PACK_SHORT_565(r, g, b);
     *(INT16 *)outptr0 = (INT16)rgb;
 
-    y  = GETJSAMPLE(*inptr01);
+    y  = *inptr01;
     r = range_limit[DITHER_565_R(y + cred, d1)];
     g = range_limit[DITHER_565_G(y + cgreen, d1)];
     b = range_limit[DITHER_565_B(y + cblue, d1)];
diff --git a/src/third_party/libjpeg-turbo/jdmrgext.c b/src/third_party/libjpeg-turbo/jdmrgext.c
index b1c27df..9bf4f1a 100644
--- a/src/third_party/libjpeg-turbo/jdmrgext.c
+++ b/src/third_party/libjpeg-turbo/jdmrgext.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2011, 2015, D. R. Commander.
+ * Copyright (C) 2011, 2015, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -25,7 +25,7 @@
                               JDIMENSION in_row_group_ctr,
                               JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr;
@@ -46,13 +46,13 @@
   /* Loop for each pair of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
     /* Fetch 2 Y values and emit 2 pixels */
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     outptr[RGB_RED] =   range_limit[y + cred];
     outptr[RGB_GREEN] = range_limit[y + cgreen];
     outptr[RGB_BLUE] =  range_limit[y + cblue];
@@ -60,7 +60,7 @@
     outptr[RGB_ALPHA] = 0xFF;
 #endif
     outptr += RGB_PIXELSIZE;
-    y  = GETJSAMPLE(*inptr0++);
+    y  = *inptr0++;
     outptr[RGB_RED] =   range_limit[y + cred];
     outptr[RGB_GREEN] = range_limit[y + cgreen];
     outptr[RGB_BLUE] =  range_limit[y + cblue];
@@ -71,12 +71,12 @@
   }
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
-    y  = GETJSAMPLE(*inptr0);
+    y  = *inptr0;
     outptr[RGB_RED] =   range_limit[y + cred];
     outptr[RGB_GREEN] = range_limit[y + cgreen];
     outptr[RGB_BLUE] =  range_limit[y + cblue];
@@ -97,7 +97,7 @@
                               JDIMENSION in_row_group_ctr,
                               JSAMPARRAY output_buf)
 {
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+  my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
   register int y, cred, cgreen, cblue;
   int cb, cr;
   register JSAMPROW outptr0, outptr1;
@@ -120,13 +120,13 @@
   /* Loop for each group of output pixels */
   for (col = cinfo->output_width >> 1; col > 0; col--) {
     /* Do the chroma part of the calculation */
-    cb = GETJSAMPLE(*inptr1++);
-    cr = GETJSAMPLE(*inptr2++);
+    cb = *inptr1++;
+    cr = *inptr2++;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
     /* Fetch 4 Y values and emit 4 pixels */
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     outptr0[RGB_RED] =   range_limit[y + cred];
     outptr0[RGB_GREEN] = range_limit[y + cgreen];
     outptr0[RGB_BLUE] =  range_limit[y + cblue];
@@ -134,7 +134,7 @@
     outptr0[RGB_ALPHA] = 0xFF;
 #endif
     outptr0 += RGB_PIXELSIZE;
-    y  = GETJSAMPLE(*inptr00++);
+    y  = *inptr00++;
     outptr0[RGB_RED] =   range_limit[y + cred];
     outptr0[RGB_GREEN] = range_limit[y + cgreen];
     outptr0[RGB_BLUE] =  range_limit[y + cblue];
@@ -142,7 +142,7 @@
     outptr0[RGB_ALPHA] = 0xFF;
 #endif
     outptr0 += RGB_PIXELSIZE;
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     outptr1[RGB_RED] =   range_limit[y + cred];
     outptr1[RGB_GREEN] = range_limit[y + cgreen];
     outptr1[RGB_BLUE] =  range_limit[y + cblue];
@@ -150,7 +150,7 @@
     outptr1[RGB_ALPHA] = 0xFF;
 #endif
     outptr1 += RGB_PIXELSIZE;
-    y  = GETJSAMPLE(*inptr01++);
+    y  = *inptr01++;
     outptr1[RGB_RED] =   range_limit[y + cred];
     outptr1[RGB_GREEN] = range_limit[y + cgreen];
     outptr1[RGB_BLUE] =  range_limit[y + cblue];
@@ -161,19 +161,19 @@
   }
   /* If image width is odd, do the last output column separately */
   if (cinfo->output_width & 1) {
-    cb = GETJSAMPLE(*inptr1);
-    cr = GETJSAMPLE(*inptr2);
+    cb = *inptr1;
+    cr = *inptr2;
     cred = Crrtab[cr];
     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     cblue = Cbbtab[cb];
-    y  = GETJSAMPLE(*inptr00);
+    y  = *inptr00;
     outptr0[RGB_RED] =   range_limit[y + cred];
     outptr0[RGB_GREEN] = range_limit[y + cgreen];
     outptr0[RGB_BLUE] =  range_limit[y + cblue];
 #ifdef RGB_ALPHA
     outptr0[RGB_ALPHA] = 0xFF;
 #endif
-    y  = GETJSAMPLE(*inptr01);
+    y  = *inptr01;
     outptr1[RGB_RED] =   range_limit[y + cred];
     outptr1[RGB_GREEN] = range_limit[y + cgreen];
     outptr1[RGB_BLUE] =  range_limit[y + cblue];
diff --git a/src/third_party/libjpeg-turbo/jdphuff.c b/src/third_party/libjpeg-turbo/jdphuff.c
index 4df79ee..c6d82ca 100644
--- a/src/third_party/libjpeg-turbo/jdphuff.c
+++ b/src/third_party/libjpeg-turbo/jdphuff.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1995-1997, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015-2016, D. R. Commander.
+ * Copyright (C) 2015-2016, 2018-2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -15,12 +15,16 @@
  * up to the start of the current MCU.  To do this, we copy state variables
  * into local working storage, and update them back to the permanent
  * storage only upon successful completion of an MCU.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
 #include "jdhuff.h"             /* Declarations shared with jdhuff.c */
+#include <limits.h>
 
 
 #ifdef D_PROGRESSIVE_SUPPORTED
@@ -37,25 +41,6 @@
   int last_dc_val[MAX_COMPS_IN_SCAN];   /* last DC coef for each component */
 } savable_state;
 
-/* This macro is to work around compilers with missing or broken
- * structure assignment.  You'll need to fix this code if you have
- * such a compiler and you change MAX_COMPS_IN_SCAN.
- */
-
-#ifndef NO_STRUCT_ASSIGN
-#define ASSIGN_STATE(dest, src)  ((dest) = (src))
-#else
-#if MAX_COMPS_IN_SCAN == 4
-#define ASSIGN_STATE(dest, src) \
-  ((dest).EOBRUN = (src).EOBRUN, \
-   (dest).last_dc_val[0] = (src).last_dc_val[0], \
-   (dest).last_dc_val[1] = (src).last_dc_val[1], \
-   (dest).last_dc_val[2] = (src).last_dc_val[2], \
-   (dest).last_dc_val[3] = (src).last_dc_val[3])
-#endif
-#endif
-
-
 typedef struct {
   struct jpeg_entropy_decoder pub; /* public fields */
 
@@ -98,7 +83,7 @@
   boolean is_DC_band, bad;
   int ci, coefi, tbl;
   d_derived_tbl **pdtbl;
-  int *coef_bit_ptr;
+  int *coef_bit_ptr, *prev_coef_bit_ptr;
   jpeg_component_info *compptr;
 
   is_DC_band = (cinfo->Ss == 0);
@@ -139,8 +124,15 @@
   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
     int cindex = cinfo->cur_comp_info[ci]->component_index;
     coef_bit_ptr = &cinfo->coef_bits[cindex][0];
+    prev_coef_bit_ptr = &cinfo->coef_bits[cindex + cinfo->num_components][0];
     if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
       WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+    for (coefi = MIN(cinfo->Ss, 1); coefi <= MAX(cinfo->Se, 9); coefi++) {
+      if (cinfo->input_scan_number > 1)
+        prev_coef_bit_ptr[coefi] = coef_bit_ptr[coefi];
+      else
+        prev_coef_bit_ptr[coefi] = 0;
+    }
     for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
       int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
       if (cinfo->Ah != expected)
@@ -319,7 +311,7 @@
 
     /* Load up working state */
     BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
-    ASSIGN_STATE(state, entropy->saved);
+    state = entropy->saved;
 
     /* Outer loop handles each block in the MCU */
 
@@ -340,6 +332,10 @@
       }
 
       /* Convert DC difference to actual value, update last_dc_val */
+      if ((state.last_dc_val[ci] >= 0 &&
+           s > INT_MAX - state.last_dc_val[ci]) ||
+          (state.last_dc_val[ci] < 0 && s < INT_MIN - state.last_dc_val[ci]))
+        ERREXIT(cinfo, JERR_BAD_DCT_COEF);
       s += state.last_dc_val[ci];
       state.last_dc_val[ci] = s;
       /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
@@ -348,11 +344,12 @@
 
     /* Completed MCU, so update state */
     BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
-    ASSIGN_STATE(entropy->saved, state);
+    entropy->saved = state;
   }
 
   /* Account for restart interval (no-op if not using restarts) */
-  entropy->restarts_to_go--;
+  if (cinfo->restart_interval)
+    entropy->restarts_to_go--;
 
   return TRUE;
 }
@@ -436,7 +433,8 @@
   }
 
   /* Account for restart interval (no-op if not using restarts) */
-  entropy->restarts_to_go--;
+  if (cinfo->restart_interval)
+    entropy->restarts_to_go--;
 
   return TRUE;
 }
@@ -487,7 +485,8 @@
   BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
 
   /* Account for restart interval (no-op if not using restarts) */
-  entropy->restarts_to_go--;
+  if (cinfo->restart_interval)
+    entropy->restarts_to_go--;
 
   return TRUE;
 }
@@ -630,7 +629,8 @@
   }
 
   /* Account for restart interval (no-op if not using restarts) */
-  entropy->restarts_to_go--;
+  if (cinfo->restart_interval)
+    entropy->restarts_to_go--;
 
   return TRUE;
 
@@ -668,7 +668,7 @@
   /* Create progression status table */
   cinfo->coef_bits = (int (*)[DCTSIZE2])
     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                cinfo->num_components * DCTSIZE2 *
+                                cinfo->num_components * 2 * DCTSIZE2 *
                                 sizeof(int));
   coef_bit_ptr = &cinfo->coef_bits[0][0];
   for (ci = 0; ci < cinfo->num_components; ci++)
diff --git a/src/third_party/libjpeg-turbo/jdsample.c b/src/third_party/libjpeg-turbo/jdsample.c
index 52ee9af4..eaad72a 100644
--- a/src/third_party/libjpeg-turbo/jdsample.c
+++ b/src/third_party/libjpeg-turbo/jdsample.c
@@ -8,6 +8,7 @@
  * Copyright (C) 2010, 2015-2016, D. R. Commander.
  * Copyright (C) 2014, MIPS Technologies, Inc., California.
  * Copyright (C) 2015, Google, Inc.
+ * Copyright (C) 2019-2020, Arm Limited.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -176,7 +177,7 @@
     outptr = output_data[outrow];
     outend = outptr + cinfo->output_width;
     while (outptr < outend) {
-      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
+      invalue = *inptr++;
       for (h = h_expand; h > 0; h--) {
         *outptr++ = invalue;
       }
@@ -212,7 +213,7 @@
     outptr = output_data[inrow];
     outend = outptr + cinfo->output_width;
     while (outptr < outend) {
-      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
+      invalue = *inptr++;
       *outptr++ = invalue;
       *outptr++ = invalue;
     }
@@ -241,7 +242,7 @@
     outptr = output_data[outrow];
     outend = outptr + cinfo->output_width;
     while (outptr < outend) {
-      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
+      invalue = *inptr++;
       *outptr++ = invalue;
       *outptr++ = invalue;
     }
@@ -282,20 +283,20 @@
     inptr = input_data[inrow];
     outptr = output_data[inrow];
     /* Special case for first column */
-    invalue = GETJSAMPLE(*inptr++);
+    invalue = *inptr++;
     *outptr++ = (JSAMPLE)invalue;
-    *outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
+    *outptr++ = (JSAMPLE)((invalue * 3 + inptr[0] + 2) >> 2);
 
     for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
       /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
-      invalue = GETJSAMPLE(*inptr++) * 3;
-      *outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
-      *outptr++ = (JSAMPLE)((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
+      invalue = (*inptr++) * 3;
+      *outptr++ = (JSAMPLE)((invalue + inptr[-2] + 1) >> 2);
+      *outptr++ = (JSAMPLE)((invalue + inptr[0] + 2) >> 2);
     }
 
     /* Special case for last column */
-    invalue = GETJSAMPLE(*inptr);
-    *outptr++ = (JSAMPLE)((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
+    invalue = *inptr;
+    *outptr++ = (JSAMPLE)((invalue * 3 + inptr[-1] + 1) >> 2);
     *outptr++ = (JSAMPLE)invalue;
   }
 }
@@ -315,9 +316,9 @@
   JSAMPARRAY output_data = *output_data_ptr;
   JSAMPROW inptr0, inptr1, outptr;
 #if BITS_IN_JSAMPLE == 8
-  int thiscolsum;
+  int thiscolsum, bias;
 #else
-  JLONG thiscolsum;
+  JLONG thiscolsum, bias;
 #endif
   JDIMENSION colctr;
   int inrow, outrow, v;
@@ -327,15 +328,18 @@
     for (v = 0; v < 2; v++) {
       /* inptr0 points to nearest input row, inptr1 points to next nearest */
       inptr0 = input_data[inrow];
-      if (v == 0)               /* next nearest is row above */
+      if (v == 0) {             /* next nearest is row above */
         inptr1 = input_data[inrow - 1];
-      else                      /* next nearest is row below */
+        bias = 1;
+      } else {                  /* next nearest is row below */
         inptr1 = input_data[inrow + 1];
+        bias = 2;
+      }
       outptr = output_data[outrow++];
 
       for (colctr = 0; colctr < compptr->downsampled_width; colctr++) {
-        thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
-        *outptr++ = (JSAMPLE)((thiscolsum + 1) >> 2);
+        thiscolsum = (*inptr0++) * 3 + (*inptr1++);
+        *outptr++ = (JSAMPLE)((thiscolsum + bias) >> 2);
       }
     }
     inrow++;
@@ -377,8 +381,8 @@
       outptr = output_data[outrow++];
 
       /* Special case for first column */
-      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
-      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+      thiscolsum = (*inptr0++) * 3 + (*inptr1++);
+      nextcolsum = (*inptr0++) * 3 + (*inptr1++);
       *outptr++ = (JSAMPLE)((thiscolsum * 4 + 8) >> 4);
       *outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
       lastcolsum = thiscolsum;  thiscolsum = nextcolsum;
@@ -386,7 +390,7 @@
       for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
         /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
         /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
-        nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+        nextcolsum = (*inptr0++) * 3 + (*inptr1++);
         *outptr++ = (JSAMPLE)((thiscolsum * 3 + lastcolsum + 8) >> 4);
         *outptr++ = (JSAMPLE)((thiscolsum * 3 + nextcolsum + 7) >> 4);
         lastcolsum = thiscolsum;  thiscolsum = nextcolsum;
@@ -473,7 +477,13 @@
     } else if (h_in_group == h_out_group &&
                v_in_group * 2 == v_out_group && do_fancy) {
       /* Non-fancy upsampling is handled by the generic method */
-      upsample->methods[ci] = h1v2_fancy_upsample;
+#if defined(__arm__) || defined(__aarch64__) || \
+    defined(_M_ARM) || defined(_M_ARM64)
+      if (jsimd_can_h1v2_fancy_upsample())
+        upsample->methods[ci] = jsimd_h1v2_fancy_upsample;
+      else
+#endif
+        upsample->methods[ci] = h1v2_fancy_upsample;
       upsample->pub.need_context_rows = TRUE;
     } else if (h_in_group * 2 == h_out_group &&
                v_in_group * 2 == v_out_group) {
diff --git a/src/third_party/libjpeg-turbo/jdtrans.c b/src/third_party/libjpeg-turbo/jdtrans.c
index 56713ef..d7ec4b8 100644
--- a/src/third_party/libjpeg-turbo/jdtrans.c
+++ b/src/third_party/libjpeg-turbo/jdtrans.c
@@ -3,8 +3,8 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1995-1997, Thomas G. Lane.
- * It was modified by The libjpeg-turbo Project to include only code relevant
- * to libjpeg-turbo.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -16,6 +16,7 @@
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
+#include "jpegcomp.h"
 
 
 /* Forward declarations */
diff --git a/src/third_party/libjpeg-turbo/jerror.h b/src/third_party/libjpeg-turbo/jerror.h
index 933a369..4476df2 100644
--- a/src/third_party/libjpeg-turbo/jerror.h
+++ b/src/third_party/libjpeg-turbo/jerror.h
@@ -207,6 +207,10 @@
 #endif
 #endif
 JMESSAGE(JWRN_BOGUS_ICC, "Corrupt JPEG data: bad ICC marker")
+#if JPEG_LIB_VERSION < 70
+JMESSAGE(JERR_BAD_DROP_SAMPLING,
+         "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
+#endif
 
 #ifdef JMAKE_ENUM_LIST
 
@@ -252,6 +256,15 @@
    (cinfo)->err->msg_parm.i[2] = (p3), \
    (cinfo)->err->msg_parm.i[3] = (p4), \
    (*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
+#define ERREXIT6(cinfo, code, p1, p2, p3, p4, p5, p6) \
+  ((cinfo)->err->msg_code = (code), \
+   (cinfo)->err->msg_parm.i[0] = (p1), \
+   (cinfo)->err->msg_parm.i[1] = (p2), \
+   (cinfo)->err->msg_parm.i[2] = (p3), \
+   (cinfo)->err->msg_parm.i[3] = (p4), \
+   (cinfo)->err->msg_parm.i[4] = (p5), \
+   (cinfo)->err->msg_parm.i[5] = (p6), \
+   (*(cinfo)->err->error_exit) ((j_common_ptr)(cinfo)))
 #define ERREXITS(cinfo, code, str) \
   ((cinfo)->err->msg_code = (code), \
    strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
diff --git a/src/third_party/libjpeg-turbo/jfdctint.c b/src/third_party/libjpeg-turbo/jfdctint.c
index c0391a9..c95a3a7 100644
--- a/src/third_party/libjpeg-turbo/jfdctint.c
+++ b/src/third_party/libjpeg-turbo/jfdctint.c
@@ -1,14 +1,14 @@
 /*
  * jfdctint.c
  *
- * This file was part of the Independent JPEG Group's software.
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015, D. R. Commander.
+ * Copyright (C) 2015, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
- * This file contains a slow-but-accurate integer implementation of the
+ * This file contains a slower but more accurate integer implementation of the
  * forward DCT (Discrete Cosine Transform).
  *
  * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
diff --git a/src/third_party/libjpeg-turbo/jidctint.c b/src/third_party/libjpeg-turbo/jidctint.c
index 5557342..bb08748 100644
--- a/src/third_party/libjpeg-turbo/jidctint.c
+++ b/src/third_party/libjpeg-turbo/jidctint.c
@@ -1,15 +1,15 @@
 /*
  * jidctint.c
  *
- * This file was part of the Independent JPEG Group's software.
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1998, Thomas G. Lane.
- * Modification developed 2002-2009 by Guido Vollbeding.
+ * Modification developed 2002-2018 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015, D. R. Commander.
+ * Copyright (C) 2015, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
- * This file contains a slow-but-accurate integer implementation of the
+ * This file contains a slower but more accurate integer implementation of the
  * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
  * must also perform dequantization of the input coefficients.
  *
@@ -417,7 +417,7 @@
 
 /*
  * Perform dequantization and inverse DCT on one block of coefficients,
- * producing a 7x7 output block.
+ * producing a reduced-size 7x7 output block.
  *
  * Optimized algorithm with 12 multiplications in the 1-D kernel.
  * cK represents sqrt(2) * cos(K*pi/14).
@@ -1258,7 +1258,7 @@
 
 /*
  * Perform dequantization and inverse DCT on one block of coefficients,
- * producing a 11x11 output block.
+ * producing an 11x11 output block.
  *
  * Optimized algorithm with 24 multiplications in the 1-D kernel.
  * cK represents sqrt(2) * cos(K*pi/22).
@@ -2398,7 +2398,7 @@
     tmp0 = DEQUANTIZE(inptr[DCTSIZE * 0], quantptr[DCTSIZE * 0]);
     tmp0 = LEFT_SHIFT(tmp0, CONST_BITS);
     /* Add fudge factor here for final descale. */
-    tmp0 += 1 << (CONST_BITS - PASS1_BITS - 1);
+    tmp0 += ONE << (CONST_BITS - PASS1_BITS - 1);
 
     z1 = DEQUANTIZE(inptr[DCTSIZE * 4], quantptr[DCTSIZE * 4]);
     tmp1 = MULTIPLY(z1, FIX(1.306562965));      /* c4[16] = c2[8] */
diff --git a/src/third_party/libjpeg-turbo/jidctred.c b/src/third_party/libjpeg-turbo/jidctred.c
index 1ff352f..1dd65a9 100644
--- a/src/third_party/libjpeg-turbo/jidctred.c
+++ b/src/third_party/libjpeg-turbo/jidctred.c
@@ -1,7 +1,7 @@
 /*
  * jidctred.c
  *
- * This file was part of the Independent JPEG Group's software.
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1998, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2015, D. R. Commander.
diff --git a/src/third_party/libjpeg-turbo/jinclude.h b/src/third_party/libjpeg-turbo/jinclude.h
index 3a1b3fe..67502b9 100644
--- a/src/third_party/libjpeg-turbo/jinclude.h
+++ b/src/third_party/libjpeg-turbo/jinclude.h
@@ -53,6 +53,7 @@
 
 #include <stdio.h>
 #endif
+
 /*
  * We need memory copying and zeroing functions, plus strncpy().
  * ANSI and System V implementations declare these in <string.h>.
@@ -66,8 +67,8 @@
 #if defined(NEED_STARBOARD_MEMORY)
 
 #include "starboard/memory.h"
-#define MEMZERO(target,size)	memset((void *)(target), 0, (size_t)(size))
-#define MEMCOPY(dest,src,size)	memcpy((void *)(dest), (const void *)(src), (size_t)(size))
+#define MEMZERO(target,size)   memset((void *)(target), 0, (size_t)(size))
+#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
 
 #elif NEED_BSD_STRINGS
 
diff --git a/src/third_party/libjpeg-turbo/jmemsys.h b/src/third_party/libjpeg-turbo/jmemsys.h
index 535e887..5cb61b2 100644
--- a/src/third_party/libjpeg-turbo/jmemsys.h
+++ b/src/third_party/libjpeg-turbo/jmemsys.h
@@ -142,7 +142,11 @@
   char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
 #else
   /* For a typical implementation with temp files, we need: */
+#if defined(STARBOARD)
   SbFile *temp_file;              /* stdio reference to temp file */
+#else
+  FILE *temp_file;              /* stdio reference to temp file */
+#endif
   char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
 #endif
 #endif
diff --git a/src/third_party/libjpeg-turbo/jmorecfg.h b/src/third_party/libjpeg-turbo/jmorecfg.h
index 08d1d50..fb3a9cf 100644
--- a/src/third_party/libjpeg-turbo/jmorecfg.h
+++ b/src/third_party/libjpeg-turbo/jmorecfg.h
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 1997-2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
+ * Copyright (C) 2009, 2011, 2014-2015, 2018, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -17,9 +17,9 @@
 
 /*
  * Maximum number of components (color channels) allowed in JPEG image.
- * To meet the letter of the JPEG spec, set this to 255.  However, darn
- * few applications need more than 4 channels (maybe 5 for CMYK + alpha
- * mask).  We recommend 10 as a reasonable compromise; use 4 if you are
+ * To meet the letter of Rec. ITU-T T.81 | ISO/IEC 10918-1, set this to 255.
+ * However, darn few applications need more than 4 channels (maybe 5 for CMYK +
+ * alpha mask).  We recommend 10 as a reasonable compromise; use 4 if you are
  * really short on memory.  (Each allowed component costs a hundred or so
  * bytes of storage, whether actually used in an image or not.)
  */
@@ -43,25 +43,11 @@
 
 #if BITS_IN_JSAMPLE == 8
 /* JSAMPLE should be the smallest type that will hold the values 0..255.
- * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
  */
 
-#ifdef HAVE_UNSIGNED_CHAR
-
 typedef unsigned char JSAMPLE;
 #define GETJSAMPLE(value)  ((int)(value))
 
-#else /* not HAVE_UNSIGNED_CHAR */
-
-typedef char JSAMPLE;
-#ifdef __CHAR_UNSIGNED__
-#define GETJSAMPLE(value)  ((int)(value))
-#else
-#define GETJSAMPLE(value)  ((int)(value) & 0xFF)
-#endif /* __CHAR_UNSIGNED__ */
-
-#endif /* HAVE_UNSIGNED_CHAR */
-
 #define MAXJSAMPLE      255
 #define CENTERJSAMPLE   128
 
@@ -97,22 +83,9 @@
  * managers, this is also the data type passed to fread/fwrite.
  */
 
-#ifdef HAVE_UNSIGNED_CHAR
-
 typedef unsigned char JOCTET;
 #define GETJOCTET(value)  (value)
 
-#else /* not HAVE_UNSIGNED_CHAR */
-
-typedef char JOCTET;
-#ifdef __CHAR_UNSIGNED__
-#define GETJOCTET(value)  (value)
-#else
-#define GETJOCTET(value)  ((value) & 0xFF)
-#endif /* __CHAR_UNSIGNED__ */
-
-#endif /* HAVE_UNSIGNED_CHAR */
-
 
 /* These typedefs are used for various table entries and so forth.
  * They must be at least as wide as specified; but making them too big
@@ -123,15 +96,7 @@
 
 /* UINT8 must hold at least the values 0..255. */
 
-#ifdef HAVE_UNSIGNED_CHAR
 typedef unsigned char UINT8;
-#else /* not HAVE_UNSIGNED_CHAR */
-#ifdef __CHAR_UNSIGNED__
-typedef char UINT8;
-#else /* not __CHAR_UNSIGNED__ */
-typedef short UINT8;
-#endif /* __CHAR_UNSIGNED__ */
-#endif /* HAVE_UNSIGNED_CHAR */
 
 /* UINT16 must hold at least the values 0..65535. */
 
@@ -273,9 +238,9 @@
 
 /* Capability options common to encoder and decoder: */
 
-#define DCT_ISLOW_SUPPORTED     /* slow but accurate integer algorithm */
-#define DCT_IFAST_SUPPORTED     /* faster, less accurate integer method */
-#define DCT_FLOAT_SUPPORTED     /* floating-point: accurate, fast on fast HW */
+#define DCT_ISLOW_SUPPORTED     /* accurate integer method */
+#define DCT_IFAST_SUPPORTED     /* less accurate int method [legacy feature] */
+#define DCT_FLOAT_SUPPORTED     /* floating-point method [legacy feature] */
 
 /* Encoder capability options: */
 
diff --git a/src/third_party/libjpeg-turbo/simd/nasm/jpeg_nbits_table.inc b/src/third_party/libjpeg-turbo/jpeg_nbits_table.c
similarity index 93%
rename from src/third_party/libjpeg-turbo/simd/nasm/jpeg_nbits_table.inc
rename to src/third_party/libjpeg-turbo/jpeg_nbits_table.c
index 2ce6c28..afcee74 100644
--- a/src/third_party/libjpeg-turbo/simd/nasm/jpeg_nbits_table.inc
+++ b/src/third_party/libjpeg-turbo/jpeg_nbits_table.c
@@ -1,4097 +1,4104 @@
-jpeg_nbits_table db \
-   0,  1,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4, \
-   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, \
-   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6, \
-   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6, \
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, \
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, \
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, \
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \
+#include "jpeg_nbits_table.h"
+
+/* NOTE: Both GCC and Clang define __GNUC__ */
+#if defined __GNUC__
+__attribute__((visibility("hidden")))
+#endif
+const unsigned char jpeg_nbits_table[65536] = {
+   0,  1,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,
+   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+};
diff --git a/src/third_party/libjpeg-turbo/jpeg_nbits_table.h b/src/third_party/libjpeg-turbo/jpeg_nbits_table.h
index fcf7387..cf45b7e 100644
--- a/src/third_party/libjpeg-turbo/jpeg_nbits_table.h
+++ b/src/third_party/libjpeg-turbo/jpeg_nbits_table.h
@@ -1,4098 +1 @@
-static const unsigned char jpeg_nbits_table[65536] = {
-   0,  1,  2,  2,  3,  3,  3,  3,  4,  4,  4,  4,  4,  4,  4,  4,
-   5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
-   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-   6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-   9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
-};
+extern const unsigned char jpeg_nbits_table[65536];
\ No newline at end of file
diff --git a/src/third_party/libjpeg-turbo/jpegcomp.h b/src/third_party/libjpeg-turbo/jpegcomp.h
index b32d544..c4834ac 100644
--- a/src/third_party/libjpeg-turbo/jpegcomp.h
+++ b/src/third_party/libjpeg-turbo/jpegcomp.h
@@ -1,7 +1,7 @@
 /*
  * jpegcomp.h
  *
- * Copyright (C) 2010, D. R. Commander.
+ * Copyright (C) 2010, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -19,6 +19,7 @@
 #define _min_DCT_v_scaled_size  min_DCT_v_scaled_size
 #define _jpeg_width  jpeg_width
 #define _jpeg_height  jpeg_height
+#define JERR_ARITH_NOTIMPL  JERR_NOT_COMPILED
 #else
 #define _DCT_scaled_size  DCT_scaled_size
 #define _DCT_h_scaled_size  DCT_scaled_size
diff --git a/src/third_party/libjpeg-turbo/jpegint.h b/src/third_party/libjpeg-turbo/jpegint.h
index ad36ca8..195fbcb 100644
--- a/src/third_party/libjpeg-turbo/jpegint.h
+++ b/src/third_party/libjpeg-turbo/jpegint.h
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 1997-2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015-2016, D. R. Commander.
+ * Copyright (C) 2015-2016, 2019, D. R. Commander.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -158,6 +158,9 @@
   JDIMENSION first_MCU_col[MAX_COMPONENTS];
   JDIMENSION last_MCU_col[MAX_COMPONENTS];
   boolean jinit_upsampler_no_alloc;
+
+  /* Last iMCU row that was successfully decoded */
+  JDIMENSION last_good_iMCU_row;
 };
 
 /* Input control module */
diff --git a/src/third_party/libjpeg-turbo/jpeglib.h b/src/third_party/libjpeg-turbo/jpeglib.h
index 7ea2456..0a09a3e 100644
--- a/src/third_party/libjpeg-turbo/jpeglib.h
+++ b/src/third_party/libjpeg-turbo/jpeglib.h
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1998, Thomas G. Lane.
  * Modified 2002-2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009-2011, 2013-2014, 2016-2017, D. R. Commander.
+ * Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, D. R. Commander.
  * Copyright (C) 2015, Google, Inc.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
@@ -18,6 +18,12 @@
 #ifndef JPEGLIB_H
 #define JPEGLIB_H
 
+/* Begin chromium edits */
+#ifdef MANGLE_JPEG_NAMES
+#include "jpeglibmangler.h"
+#endif
+/* End chromium edits */
+
 /*
  * First we include the configuration files that record how this
  * installation of the JPEG library is set up.  jconfig.h can be
@@ -244,9 +250,9 @@
 /* DCT/IDCT algorithm options. */
 
 typedef enum {
-  JDCT_ISLOW,             /* slow but accurate integer algorithm */
-  JDCT_IFAST,             /* faster, less accurate integer method */
-  JDCT_FLOAT              /* floating-point: accurate, fast on fast HW */
+  JDCT_ISLOW,             /* accurate integer method */
+  JDCT_IFAST,             /* less accurate integer method [legacy feature] */
+  JDCT_FLOAT              /* floating-point method [legacy feature] */
 } J_DCT_METHOD;
 
 #ifndef JDCT_DEFAULT            /* may be overridden in jconfig.h */
@@ -913,8 +919,13 @@
 
 /* Standard data source and destination managers: stdio streams. */
 /* Caller is responsible for opening the file before and closing after. */
+#if defined(STARBOARD)
 EXTERN(void) jpeg_stdio_dest(j_compress_ptr cinfo, SbFile *outfile);
 EXTERN(void) jpeg_stdio_src(j_decompress_ptr cinfo, SbFile *infile);
+#else
+EXTERN(void) jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile);
+EXTERN(void) jpeg_stdio_src(j_decompress_ptr cinfo, FILE *infile);
+#endif
 
 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
 /* Data source and destination managers: memory buffers. */
diff --git a/src/third_party/libjpeg-turbo/jpeglibmangler.h b/src/third_party/libjpeg-turbo/jpeglibmangler.h
new file mode 100644
index 0000000..781cc2c
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/jpeglibmangler.h
@@ -0,0 +1,133 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_LIBJPEG_TURBO_JPEGLIBMANGLER_H_
+#define THIRD_PARTY_LIBJPEG_TURBO_JPEGLIBMANGLER_H_
+
+// Mangle all externally visible function names so we can build our own libjpeg
+// without system libraries trying to use it.
+
+#define jpeg_make_c_derived_tbl chromium_jpeg_make_c_derived_tbl
+#define jpeg_gen_optimal_table chromium_jpeg_gen_optimal_table
+#define jpeg_make_d_derived_tbl chromium_jpeg_make_d_derived_tbl
+#define jpeg_fill_bit_buffer chromium_jpeg_fill_bit_buffer
+#define jpeg_huff_decode chromium_jpeg_huff_decode
+#define jpeg_fdct_islow chromium_jpeg_fdct_islow
+#define jpeg_fdct_ifast chromium_jpeg_fdct_ifast
+#define jpeg_fdct_float chromium_jpeg_fdct_float
+#define jpeg_idct_islow chromium_jpeg_idct_islow
+#define jpeg_idct_ifast chromium_jpeg_idct_ifast
+#define jpeg_idct_float chromium_jpeg_idct_float
+#define jpeg_idct_16x16 chromium_jpeg_idct_16x16
+#define jpeg_idct_15x15 chromium_jpeg_idct_15x15
+#define jpeg_idct_14x14 chromium_jpeg_idct_14x14
+#define jpeg_idct_13x13 chromium_jpeg_idct_13x13
+#define jpeg_idct_12x12 chromium_jpeg_idct_12x12
+#define jpeg_idct_11x11 chromium_jpeg_idct_11x11
+#define jpeg_idct_10x10 chromium_jpeg_idct_10x10
+#define jpeg_idct_9x9 chromium_jpeg_idct_9x9
+#define jpeg_idct_7x7 chromium_jpeg_idct_7x7
+#define jpeg_idct_6x6 chromium_jpeg_idct_6x6
+#define jpeg_idct_5x5 chromium_jpeg_idct_5x5
+#define jpeg_idct_4x4 chromium_jpeg_idct_4x4
+#define jpeg_idct_3x3 chromium_jpeg_idct_3x3
+#define jpeg_idct_2x2 chromium_jpeg_idct_2x2
+#define jpeg_idct_1x1 chromium_jpeg_idct_1x1
+#define jinit_compress_master chromium_jinit_compress_master
+#define jinit_c_master_control chromium_jinit_c_master_control
+#define jinit_c_main_controller chromium_jinit_c_main_controller
+#define jinit_c_prep_controller chromium_jinit_c_prep_controller
+#define jinit_c_coef_controller chromium_jinit_c_coef_controller
+#define jinit_color_converter chromium_jinit_color_converter
+#define jinit_downsampler chromium_jinit_downsampler
+#define jinit_forward_dct chromium_jinit_forward_dct
+#define jinit_huff_encoder chromium_jinit_huff_encoder
+#define jinit_phuff_encoder chromium_jinit_phuff_encoder
+#define jinit_marker_writer chromium_jinit_marker_writer
+#define jinit_master_decompress chromium_jinit_master_decompress
+#define jinit_d_main_controller chromium_jinit_d_main_controller
+#define jinit_d_coef_controller chromium_jinit_d_coef_controller
+#define jinit_d_post_controller chromium_jinit_d_post_controller
+#define jinit_input_controller chromium_jinit_input_controller
+#define jinit_marker_reader chromium_jinit_marker_reader
+#define jinit_huff_decoder chromium_jinit_huff_decoder
+#define jinit_phuff_decoder chromium_jinit_phuff_decoder
+#define jinit_inverse_dct chromium_jinit_inverse_dct
+#define jinit_upsampler chromium_jinit_upsampler
+#define jinit_color_deconverter chromium_jinit_color_deconverter
+#define jinit_1pass_quantizer chromium_jinit_1pass_quantizer
+#define jinit_2pass_quantizer chromium_jinit_2pass_quantizer
+#define jinit_merged_upsampler chromium_jinit_merged_upsampler
+#define jinit_memory_mgr chromium_jinit_memory_mgr
+#define jdiv_round_up chromium_jdiv_round_up
+#define jround_up chromium_jround_up
+#define jcopy_sample_rows chromium_jcopy_sample_rows
+#define jcopy_block_row chromium_jcopy_block_row
+#define jzero_far chromium_jzero_far
+#define jpeg_std_error chromium_jpeg_std_error
+#define jpeg_CreateCompress chromium_jpeg_CreateCompress
+#define jpeg_CreateDecompress chromium_jpeg_CreateDecompress
+#define jpeg_destroy_compress chromium_jpeg_destroy_compress
+#define jpeg_destroy_decompress chromium_jpeg_destroy_decompress
+#define jpeg_stdio_dest chromium_jpeg_stdio_dest
+#define jpeg_stdio_src chromium_jpeg_stdio_src
+#define jpeg_set_defaults chromium_jpeg_set_defaults
+#define jpeg_set_colorspace chromium_jpeg_set_colorspace
+#define jpeg_default_colorspace chromium_jpeg_default_colorspace
+#define jpeg_set_quality chromium_jpeg_set_quality
+#define jpeg_set_linear_quality chromium_jpeg_set_linear_quality
+#define jpeg_add_quant_table chromium_jpeg_add_quant_table
+#define jpeg_quality_scaling chromium_jpeg_quality_scaling
+#define jpeg_simple_progression chromium_jpeg_simple_progression
+#define jpeg_suppress_tables chromium_jpeg_suppress_tables
+#define jpeg_alloc_quant_table chromium_jpeg_alloc_quant_table
+#define jpeg_alloc_huff_table chromium_jpeg_alloc_huff_table
+#define jpeg_start_compress chromium_jpeg_start_compress
+#define jpeg_write_scanlines chromium_jpeg_write_scanlines
+#define jpeg_finish_compress chromium_jpeg_finish_compress
+#define jpeg_read_icc_profile chromium_jpeg_read_icc_profile
+#define jpeg_write_icc_profile chromium_jpeg_write_icc_profile
+#define jpeg_write_raw_data chromium_jpeg_write_raw_data
+#define jpeg_write_marker chromium_jpeg_write_marker
+#define jpeg_write_m_header chromium_jpeg_write_m_header
+#define jpeg_write_m_byte chromium_jpeg_write_m_byte
+#define jpeg_write_tables chromium_jpeg_write_tables
+#define jpeg_read_header chromium_jpeg_read_header
+#define jpeg_start_decompress chromium_jpeg_start_decompress
+#define jpeg_read_scanlines chromium_jpeg_read_scanlines
+#define jpeg_skip_scanlines chromium_jpeg_skip_scanlines
+#define jpeg_crop_scanline chromium_jpeg_crop_scanline
+#define jpeg_finish_decompress chromium_jpeg_finish_decompress
+#define jpeg_read_raw_data chromium_jpeg_read_raw_data
+#define jpeg_has_multiple_scans chromium_jpeg_has_multiple_scans
+#define jpeg_start_output chromium_jpeg_start_output
+#define jpeg_finish_output chromium_jpeg_finish_output
+#define jpeg_input_complete chromium_jpeg_input_complete
+#define jpeg_new_colormap chromium_jpeg_new_colormap
+#define jpeg_consume_input chromium_jpeg_consume_input
+#define jpeg_calc_output_dimensions chromium_jpeg_calc_output_dimensions
+#define jpeg_save_markers chromium_jpeg_save_markers
+#define jpeg_set_marker_processor chromium_jpeg_set_marker_processor
+#define jpeg_read_coefficients chromium_jpeg_read_coefficients
+#define jpeg_write_coefficients chromium_jpeg_write_coefficients
+#define jpeg_copy_critical_parameters chromium_jpeg_copy_critical_parameters
+#define jpeg_abort_compress chromium_jpeg_abort_compress
+#define jpeg_abort_decompress chromium_jpeg_abort_decompress
+#define jpeg_abort chromium_jpeg_abort
+#define jpeg_destroy chromium_jpeg_destroy
+#define jpeg_resync_to_restart chromium_jpeg_resync_to_restart
+#define jpeg_get_small chromium_jpeg_get_small
+#define jpeg_free_small chromium_jpeg_free_small
+#define jpeg_get_large chromium_jpeg_get_large
+#define jpeg_free_large chromium_jpeg_free_large
+#define jpeg_mem_available chromium_jpeg_mem_available
+#define jpeg_mem_dest chromium_jpeg_mem_dest
+#define jpeg_mem_src chromium_jpeg_mem_src
+#define jpeg_open_backing_store chromium_jpeg_open_backing_store
+#define jpeg_mem_init chromium_jpeg_mem_init
+#define jpeg_mem_term chromium_jpeg_mem_term
+#define jpeg_std_message_table chromium_jpeg_std_message_table
+#define jpeg_natural_order chromium_jpeg_natural_order
+
+#endif  // THIRD_PARTY_LIBJPEG_TURBO_JPEGLIBMANGLER_H_
diff --git a/src/third_party/libjpeg-turbo/jpegtran.1 b/src/third_party/libjpeg-turbo/jpegtran.1
index 2efb264..da7a266 100644
--- a/src/third_party/libjpeg-turbo/jpegtran.1
+++ b/src/third_party/libjpeg-turbo/jpegtran.1
@@ -1,4 +1,4 @@
-.TH JPEGTRAN 1 "18 March 2017"
+.TH JPEGTRAN 1 "26 October 2020"
 .SH NAME
 jpegtran \- lossless transformation of JPEG files
 .SH SYNOPSIS
@@ -161,13 +161,13 @@
 .PP
 This version of \fBjpegtran\fR also offers a lossless crop option, which
 discards data outside of a given image region but losslessly preserves what is
-inside. Like the rotate and flip transforms, lossless crop is restricted by the
-current JPEG format; the upper left corner of the selected region must fall on
-an iMCU boundary.  If it doesn't, then it is silently moved up and/or left to
-the nearest iMCU boundary (the lower right corner is unchanged.)  Thus, the
+inside.  Like the rotate and flip transforms, lossless crop is restricted by
+the current JPEG format; the upper left corner of the selected region must fall
+on an iMCU boundary.  If it doesn't, then it is silently moved up and/or left
+to the nearest iMCU boundary (the lower right corner is unchanged.)  Thus, the
 output image covers at least the requested region, but it may cover more.  The
-adjustment of the region dimensions may be optionally disabled by attaching
-an 'f' character ("force") to the width or height number.
+adjustment of the region dimensions may be optionally disabled by attaching an
+'f' character ("force") to the width or height number.
 
 The image can be losslessly cropped by giving the switch:
 .TP
@@ -180,6 +180,47 @@
 doesn't, then it is silently moved up and/or left to the nearest iMCU boundary
 (the lower right corner is unchanged.)
 .PP
+If W or H is larger than the width/height of the input image, then the output
+image is expanded in size, and the expanded region is filled in with zeros
+(neutral gray).  Attaching an 'f' character ("flatten") to the width number
+will cause each block in the expanded region to be filled in with the DC
+coefficient of the nearest block in the input image rather than grayed out.
+Attaching an 'r' character ("reflect") to the width number will cause the
+expanded region to be filled in with repeated reflections of the input image
+rather than grayed out.
+.PP
+A complementary lossless wipe option is provided to discard (gray out) data
+inside a given image region while losslessly preserving what is outside:
+.TP
+.B \-wipe WxH+X+Y
+Wipe (gray out) a rectangular region of width W and height H from the input
+image, starting at point X,Y.
+.PP
+Attaching an 'f' character ("flatten") to the width number will cause the
+region to be filled with the average of adjacent blocks rather than grayed out.
+If the wipe region and the region outside the wipe region, when adjusted to the
+nearest iMCU boundary, form two horizontally adjacent rectangles, then
+attaching an 'r' character ("reflect") to the width number will cause the wipe
+region to be filled with repeated reflections of the outside region rather than
+grayed out.
+.PP
+A lossless drop option is also provided, which allows another JPEG image to be
+inserted ("dropped") into the input image data at a given position, replacing
+the existing image data at that position:
+.TP
+.B \-drop +X+Y filename
+Drop (insert) another image at point X,Y
+.PP
+Both the input image and the drop image must have the same subsampling level.
+It is best if they also have the same quantization (quality.)  Otherwise, the
+quantization of the output image will be adapted to accommodate the higher of
+the input image quality and the drop image quality.  The trim option can be
+used with the drop option to requantize the drop image to match the input
+image.  Note that a grayscale image can be dropped into a full-color image or
+vice versa, as long as the full-color image has no vertical subsampling.  If
+the input image is grayscale and the drop image is full-color, then the
+chrominance channels from the drop image will be discarded.
+.PP
 Other not-strictly-lossless transformation switches are:
 .TP
 .B \-grayscale
@@ -229,9 +270,31 @@
 .B \-max 4m
 selects 4000000 bytes.  If more space is needed, an error will occur.
 .TP
+.BI \-maxscans " N"
+Abort if the input image contains more than
+.I N
+scans.  This feature demonstrates a method by which applications can guard
+against denial-of-service attacks instigated by specially-crafted malformed
+JPEG images containing numerous scans with missing image data or image data
+consisting only of "EOB runs" (a feature of progressive JPEG images that allows
+potentially hundreds of thousands of adjoining zero-value pixels to be
+represented using only a few bytes.)  Attempting to transform such malformed
+JPEG images can cause excessive CPU activity, since the decompressor must fully
+process each scan (even if the scan is corrupt) before it can proceed to the
+next scan.
+.TP
 .BI \-outfile " name"
 Send output image to the named file, not to standard output.
 .TP
+.BI \-report
+Report transformation progress.
+.TP
+.BI \-strict
+Treat all warnings as fatal.  This feature also demonstrates a method by which
+applications can guard against attacks instigated by specially-crafted
+malformed JPEG images.  Enabling this option will cause the decompressor to
+abort if the input image contains incomplete or corrupt image data.
+.TP
 .B \-verbose
 Enable debug printout.  More
 .BR \-v 's
diff --git a/src/third_party/libjpeg-turbo/jpegtran.c b/src/third_party/libjpeg-turbo/jpegtran.c
index 058e844..90fda7d 100644
--- a/src/third_party/libjpeg-turbo/jpegtran.c
+++ b/src/third_party/libjpeg-turbo/jpegtran.c
@@ -2,9 +2,9 @@
  * jpegtran.c
  *
  * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1995-2019, Thomas G. Lane, Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2014, 2017, D. R. Commander.
+ * Copyright (C) 2010, 2014, 2017, 2019-2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -41,7 +41,11 @@
 
 static const char *progname;    /* program name for error messages */
 static char *icc_filename;      /* for -icc switch */
+static JDIMENSION max_scans;    /* for -maxscans switch */
 static char *outfilename;       /* for -outfile switch */
+static char *dropfilename;      /* for -drop switch */
+static boolean report;          /* for -report switch */
+static boolean strict;          /* for -strict switch */
 static JCOPY_OPTION copyoption; /* -copy switch */
 static jpeg_transform_info transformoption; /* image transformation options */
 
@@ -69,9 +73,10 @@
 #endif
   fprintf(stderr, "Switches for modifying the image:\n");
 #if TRANSFORMS_SUPPORTED
-  fprintf(stderr, "  -crop WxH+X+Y  Crop to a rectangular subarea\n");
-  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
+  fprintf(stderr, "  -crop WxH+X+Y  Crop to a rectangular region\n");
+  fprintf(stderr, "  -drop +X+Y filename          Drop (insert) another image\n");
   fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
+  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
   fprintf(stderr, "  -perfect       Fail if there is non-transformable edge blocks\n");
   fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
 #endif
@@ -79,6 +84,8 @@
   fprintf(stderr, "  -transpose     Transpose image\n");
   fprintf(stderr, "  -transverse    Transverse transpose image\n");
   fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
+  fprintf(stderr, "                 with -drop: Requantize drop file to match source file\n");
+  fprintf(stderr, "  -wipe WxH+X+Y  Wipe (gray out) a rectangular region\n");
 #endif
   fprintf(stderr, "Switches for advanced users:\n");
 #ifdef C_ARITH_CODING_SUPPORTED
@@ -87,7 +94,10 @@
   fprintf(stderr, "  -icc FILE      Embed ICC profile contained in FILE\n");
   fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
+  fprintf(stderr, "  -maxscans N    Maximum number of scans to allow in input file\n");
   fprintf(stderr, "  -outfile name  Specify name for output file\n");
+  fprintf(stderr, "  -report        Report transformation progress\n");
+  fprintf(stderr, "  -strict        Treat all warnings as fatal\n");
   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
   fprintf(stderr, "  -version       Print version information and exit\n");
   fprintf(stderr, "Switches for wizards:\n");
@@ -141,7 +151,10 @@
   /* Set up default JPEG parameters. */
   simple_progressive = FALSE;
   icc_filename = NULL;
+  max_scans = 0;
   outfilename = NULL;
+  report = FALSE;
+  strict = FALSE;
   copyoption = JCOPYOPT_DEFAULT;
   transformoption.transform = JXFORM_NONE;
   transformoption.perfect = FALSE;
@@ -193,7 +206,8 @@
 #if TRANSFORMS_SUPPORTED
       if (++argn >= argc)       /* advance to next argument */
         usage();
-      if (!jtransform_parse_crop_spec(&transformoption, argv[argn])) {
+      if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
+          !jtransform_parse_crop_spec(&transformoption, argv[argn])) {
         fprintf(stderr, "%s: bogus -crop argument '%s'\n",
                 progname, argv[argn]);
         exit(EXIT_FAILURE);
@@ -202,6 +216,26 @@
       select_transform(JXFORM_NONE);    /* force an error */
 #endif
 
+    } else if (keymatch(arg, "drop", 2)) {
+#if TRANSFORMS_SUPPORTED
+      if (++argn >= argc)       /* advance to next argument */
+        usage();
+      if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
+          !jtransform_parse_crop_spec(&transformoption, argv[argn]) ||
+          transformoption.crop_width_set != JCROP_UNSET ||
+          transformoption.crop_height_set != JCROP_UNSET) {
+        fprintf(stderr, "%s: bogus -drop argument '%s'\n",
+                progname, argv[argn]);
+        exit(EXIT_FAILURE);
+      }
+      if (++argn >= argc)       /* advance to next argument */
+        usage();
+      dropfilename = argv[argn];
+      select_transform(JXFORM_DROP);
+#else
+      select_transform(JXFORM_NONE);    /* force an error */
+#endif
+
     } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
       /* Enable debug printouts. */
       /* On first -d, print version identification */
@@ -261,6 +295,12 @@
         lval *= 1000L;
       cinfo->mem->max_memory_to_use = lval * 1000L;
 
+    } else if (keymatch(arg, "maxscans", 4)) {
+      if (++argn >= argc)       /* advance to next argument */
+        usage();
+      if (sscanf(argv[argn], "%u", &max_scans) != 1)
+        usage();
+
     } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
       /* Enable entropy parm optimization. */
 #ifdef ENTROPY_OPT_SUPPORTED
@@ -293,6 +333,9 @@
       exit(EXIT_FAILURE);
 #endif
 
+    } else if (keymatch(arg, "report", 3)) {
+      report = TRUE;
+
     } else if (keymatch(arg, "restart", 1)) {
       /* Restart interval in MCU rows (or in MCUs with 'b'). */
       long lval;
@@ -338,6 +381,9 @@
       exit(EXIT_FAILURE);
 #endif
 
+    } else if (keymatch(arg, "strict", 2)) {
+      strict = TRUE;
+
     } else if (keymatch(arg, "transpose", 1)) {
       /* Transpose (across UL-to-LR axis). */
       select_transform(JXFORM_TRANSPOSE);
@@ -350,6 +396,21 @@
       /* Trim off any partial edge MCUs that the transform can't handle. */
       transformoption.trim = TRUE;
 
+    } else if (keymatch(arg, "wipe", 1)) {
+#if TRANSFORMS_SUPPORTED
+      if (++argn >= argc)       /* advance to next argument */
+        usage();
+      if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
+          !jtransform_parse_crop_spec(&transformoption, argv[argn])) {
+        fprintf(stderr, "%s: bogus -wipe argument '%s'\n",
+                progname, argv[argn]);
+        exit(EXIT_FAILURE);
+      }
+      select_transform(JXFORM_WIPE);
+#else
+      select_transform(JXFORM_NONE);    /* force an error */
+#endif
+
     } else {
       usage();                  /* bogus switch */
     }
@@ -375,19 +436,39 @@
 }
 
 
+METHODDEF(void)
+my_emit_message(j_common_ptr cinfo, int msg_level)
+{
+  if (msg_level < 0) {
+    /* Treat warning as fatal */
+    cinfo->err->error_exit(cinfo);
+  } else {
+    if (cinfo->err->trace_level >= msg_level)
+      cinfo->err->output_message(cinfo);
+  }
+}
+
+
 /*
  * The main program.
  */
 
 int
+#ifdef GTEST
+jpegtran(int argc, char **argv)
+#else
 main(int argc, char **argv)
+#endif
 {
   struct jpeg_decompress_struct srcinfo;
+#if TRANSFORMS_SUPPORTED
+  struct jpeg_decompress_struct dropinfo;
+  struct jpeg_error_mgr jdroperr;
+  FILE *drop_file;
+#endif
   struct jpeg_compress_struct dstinfo;
   struct jpeg_error_mgr jsrcerr, jdsterr;
-#ifdef PROGRESS_REPORT
-  struct cdjpeg_progress_mgr progress;
-#endif
+  struct cdjpeg_progress_mgr src_progress, dst_progress;
   jvirt_barray_ptr *src_coef_arrays;
   jvirt_barray_ptr *dst_coef_arrays;
   int file_index;
@@ -420,13 +501,16 @@
    * values read here are mostly ignored; we will rescan the switches after
    * opening the input file.  Also note that most of the switches affect the
    * destination JPEG object, so we parse into that and then copy over what
-   * needs to affects the source too.
+   * needs to affect the source too.
    */
 
   file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
   jsrcerr.trace_level = jdsterr.trace_level;
   srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
 
+  if (strict)
+    jsrcerr.emit_message = my_emit_message;
+
 #ifdef TWO_FILE_COMMANDLINE
   /* Must have either -outfile switch or explicit output file name */
   if (outfilename == NULL) {
@@ -456,7 +540,7 @@
     if ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s for reading\n", progname,
               argv[file_index]);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else {
     /* default input file is stdin */
@@ -466,34 +550,55 @@
   if (icc_filename != NULL) {
     if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if (fseek(icc_file, 0, SEEK_END) < 0 ||
         (icc_len = ftell(icc_file)) < 1 ||
         fseek(icc_file, 0, SEEK_SET) < 0) {
       fprintf(stderr, "%s: can't determine size of %s\n", progname,
               icc_filename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
       fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
       fclose(icc_file);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
       fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
               icc_filename);
       free(icc_profile);
       fclose(icc_file);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
     fclose(icc_file);
     if (copyoption == JCOPYOPT_ALL)
       copyoption = JCOPYOPT_ALL_EXCEPT_ICC;
   }
 
-#ifdef PROGRESS_REPORT
-  start_progress_monitor((j_common_ptr)&dstinfo, &progress);
+  if (report) {
+    start_progress_monitor((j_common_ptr)&dstinfo, &dst_progress);
+    dst_progress.report = report;
+  }
+  if (report || max_scans != 0) {
+    start_progress_monitor((j_common_ptr)&srcinfo, &src_progress);
+    src_progress.report = report;
+    src_progress.max_scans = max_scans;
+  }
+#if TRANSFORMS_SUPPORTED
+  /* Open the drop file. */
+  if (dropfilename != NULL) {
+    if ((drop_file = fopen(dropfilename, READ_BINARY)) == NULL) {
+      fprintf(stderr, "%s: can't open %s for reading\n", progname,
+              dropfilename);
+      return EXIT_FAILURE;
+    }
+    dropinfo.err = jpeg_std_error(&jdroperr);
+    jpeg_create_decompress(&dropinfo);
+    jpeg_stdio_src(&dropinfo, drop_file);
+  } else {
+    drop_file = NULL;
+  }
 #endif
 
   /* Specify data source for decompression */
@@ -505,6 +610,17 @@
   /* Read file header */
   (void)jpeg_read_header(&srcinfo, TRUE);
 
+#if TRANSFORMS_SUPPORTED
+  if (dropfilename != NULL) {
+    (void)jpeg_read_header(&dropinfo, TRUE);
+    transformoption.crop_width = dropinfo.image_width;
+    transformoption.crop_width_set = JCROP_POS;
+    transformoption.crop_height = dropinfo.image_height;
+    transformoption.crop_height_set = JCROP_POS;
+    transformoption.drop_ptr = &dropinfo;
+  }
+#endif
+
   /* Any space needed by a transform option must be requested before
    * jpeg_read_coefficients so that memory allocation will be done right.
    */
@@ -513,13 +629,19 @@
    */
   if (!jtransform_request_workspace(&srcinfo, &transformoption)) {
     fprintf(stderr, "%s: transformation is not perfect\n", progname);
-    exit(EXIT_FAILURE);
+    return EXIT_FAILURE;
   }
 #endif
 
   /* Read source file as DCT coefficients */
   src_coef_arrays = jpeg_read_coefficients(&srcinfo);
 
+#if TRANSFORMS_SUPPORTED
+  if (dropfilename != NULL) {
+    transformoption.drop_coef_arrays = jpeg_read_coefficients(&dropinfo);
+  }
+#endif
+
   /* Initialize destination compression parameters from source values */
   jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
 
@@ -549,7 +671,7 @@
     if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
       fprintf(stderr, "%s: can't open %s for writing\n", progname,
               outfilename);
-      exit(EXIT_FAILURE);
+      return EXIT_FAILURE;
     }
   } else {
     /* default output file is stdout */
@@ -580,22 +702,36 @@
   /* Finish compression and release memory */
   jpeg_finish_compress(&dstinfo);
   jpeg_destroy_compress(&dstinfo);
+#if TRANSFORMS_SUPPORTED
+  if (dropfilename != NULL) {
+    (void)jpeg_finish_decompress(&dropinfo);
+    jpeg_destroy_decompress(&dropinfo);
+  }
+#endif
   (void)jpeg_finish_decompress(&srcinfo);
   jpeg_destroy_decompress(&srcinfo);
 
   /* Close output file, if we opened it */
   if (fp != stdout)
     fclose(fp);
-
-#ifdef PROGRESS_REPORT
-  end_progress_monitor((j_common_ptr)&dstinfo);
+#if TRANSFORMS_SUPPORTED
+  if (drop_file != NULL)
+    fclose(drop_file);
 #endif
 
-  if (icc_profile != NULL)
-    free(icc_profile);
+  if (report)
+    end_progress_monitor((j_common_ptr)&dstinfo);
+  if (report || max_scans != 0)
+    end_progress_monitor((j_common_ptr)&srcinfo);
+
+  free(icc_profile);
 
   /* All done. */
-  exit(jsrcerr.num_warnings + jdsterr.num_warnings ?
-       EXIT_WARNING : EXIT_SUCCESS);
-  return 0;                     /* suppress no-return-value warnings */
+#if TRANSFORMS_SUPPORTED
+  if (dropfilename != NULL)
+    return (jsrcerr.num_warnings + jdroperr.num_warnings +
+            jdsterr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
+#endif
+  return (jsrcerr.num_warnings + jdsterr.num_warnings ?
+          EXIT_WARNING : EXIT_SUCCESS);
 }
diff --git a/src/third_party/libjpeg-turbo/jquant1.c b/src/third_party/libjpeg-turbo/jquant1.c
index a336abd..73b83e1 100644
--- a/src/third_party/libjpeg-turbo/jquant1.c
+++ b/src/third_party/libjpeg-turbo/jquant1.c
@@ -154,7 +154,7 @@
    */
   boolean is_padded;            /* is the colorindex padded for odither? */
 
-  int Ncolors[MAX_Q_COMPS];     /* # of values alloced to each component */
+  int Ncolors[MAX_Q_COMPS];     /* # of values allocated to each component */
 
   /* Variables for ordered dithering */
   int row_index;                /* cur row's vertical index in dither matrix */
@@ -479,7 +479,7 @@
     for (col = width; col > 0; col--) {
       pixcode = 0;
       for (ci = 0; ci < nc; ci++) {
-        pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
+        pixcode += colorindex[ci][*ptrin++];
       }
       *ptrout++ = (JSAMPLE)pixcode;
     }
@@ -506,9 +506,9 @@
     ptrin = input_buf[row];
     ptrout = output_buf[row];
     for (col = width; col > 0; col--) {
-      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
-      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
-      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
+      pixcode  = colorindex0[*ptrin++];
+      pixcode += colorindex1[*ptrin++];
+      pixcode += colorindex2[*ptrin++];
       *ptrout++ = (JSAMPLE)pixcode;
     }
   }
@@ -552,7 +552,7 @@
          * required amount of padding.
          */
         *output_ptr +=
-          colorindex_ci[GETJSAMPLE(*input_ptr) + dither[col_index]];
+          colorindex_ci[*input_ptr + dither[col_index]];
         input_ptr += nc;
         output_ptr++;
         col_index = (col_index + 1) & ODITHER_MASK;
@@ -595,12 +595,9 @@
     col_index = 0;
 
     for (col = width; col > 0; col--) {
-      pixcode  =
-        GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + dither0[col_index]]);
-      pixcode +=
-        GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + dither1[col_index]]);
-      pixcode +=
-        GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + dither2[col_index]]);
+      pixcode  = colorindex0[(*input_ptr++) + dither0[col_index]];
+      pixcode += colorindex1[(*input_ptr++) + dither1[col_index]];
+      pixcode += colorindex2[(*input_ptr++) + dither2[col_index]];
       *output_ptr++ = (JSAMPLE)pixcode;
       col_index = (col_index + 1) & ODITHER_MASK;
     }
@@ -677,15 +674,15 @@
          * The maximum error is +- MAXJSAMPLE; this sets the required size
          * of the range_limit array.
          */
-        cur += GETJSAMPLE(*input_ptr);
-        cur = GETJSAMPLE(range_limit[cur]);
+        cur += *input_ptr;
+        cur = range_limit[cur];
         /* Select output value, accumulate into output code for this pixel */
-        pixcode = GETJSAMPLE(colorindex_ci[cur]);
+        pixcode = colorindex_ci[cur];
         *output_ptr += (JSAMPLE)pixcode;
         /* Compute actual representation error at this pixel */
         /* Note: we can do this even though we don't have the final */
         /* pixel code, because the colormap is orthogonal. */
-        cur -= GETJSAMPLE(colormap_ci[pixcode]);
+        cur -= colormap_ci[pixcode];
         /* Compute error fractions to be propagated to adjacent pixels.
          * Add these into the running sums, and simultaneously shift the
          * next-line error sums left by 1 column.
diff --git a/src/third_party/libjpeg-turbo/jquant2.c b/src/third_party/libjpeg-turbo/jquant2.c
index 0ce0ca5..44efb18 100644
--- a/src/third_party/libjpeg-turbo/jquant2.c
+++ b/src/third_party/libjpeg-turbo/jquant2.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2009, 2014-2015, D. R. Commander.
+ * Copyright (C) 2009, 2014-2015, 2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -215,9 +215,9 @@
     ptr = input_buf[row];
     for (col = width; col > 0; col--) {
       /* get pixel value and index into the histogram */
-      histp = &histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
-                        [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
-                        [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
+      histp = &histogram[ptr[0] >> C0_SHIFT]
+                        [ptr[1] >> C1_SHIFT]
+                        [ptr[2] >> C2_SHIFT];
       /* increment, check for overflow and undo increment if so. */
       if (++(*histp) <= 0)
         (*histp)--;
@@ -665,7 +665,7 @@
 
   for (i = 0; i < numcolors; i++) {
     /* We compute the squared-c0-distance term, then add in the other two. */
-    x = GETJSAMPLE(cinfo->colormap[0][i]);
+    x = cinfo->colormap[0][i];
     if (x < minc0) {
       tdist = (x - minc0) * C0_SCALE;
       min_dist = tdist * tdist;
@@ -688,7 +688,7 @@
       }
     }
 
-    x = GETJSAMPLE(cinfo->colormap[1][i]);
+    x = cinfo->colormap[1][i];
     if (x < minc1) {
       tdist = (x - minc1) * C1_SCALE;
       min_dist += tdist * tdist;
@@ -710,7 +710,7 @@
       }
     }
 
-    x = GETJSAMPLE(cinfo->colormap[2][i]);
+    x = cinfo->colormap[2][i];
     if (x < minc2) {
       tdist = (x - minc2) * C2_SCALE;
       min_dist += tdist * tdist;
@@ -788,13 +788,13 @@
 #define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
 
   for (i = 0; i < numcolors; i++) {
-    icolor = GETJSAMPLE(colorlist[i]);
+    icolor = colorlist[i];
     /* Compute (square of) distance from minc0/c1/c2 to this color */
-    inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
+    inc0 = (minc0 - cinfo->colormap[0][icolor]) * C0_SCALE;
     dist0 = inc0 * inc0;
-    inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
+    inc1 = (minc1 - cinfo->colormap[1][icolor]) * C1_SCALE;
     dist0 += inc1 * inc1;
-    inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
+    inc2 = (minc2 - cinfo->colormap[2][icolor]) * C2_SCALE;
     dist0 += inc2 * inc2;
     /* Form the initial difference increments */
     inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
@@ -879,7 +879,7 @@
     for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
       cachep = &histogram[c0 + ic0][c1 + ic1][c2];
       for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
-        *cachep++ = (histcell)(GETJSAMPLE(*cptr++) + 1);
+        *cachep++ = (histcell)((*cptr++) + 1);
       }
     }
   }
@@ -909,9 +909,9 @@
     outptr = output_buf[row];
     for (col = width; col > 0; col--) {
       /* get pixel value and index into the cache */
-      c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
-      c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
-      c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
+      c0 = (*inptr++) >> C0_SHIFT;
+      c1 = (*inptr++) >> C1_SHIFT;
+      c2 = (*inptr++) >> C2_SHIFT;
       cachep = &histogram[c0][c1][c2];
       /* If we have not seen this color before, find nearest colormap entry */
       /* and update the cache */
@@ -996,12 +996,12 @@
        * The maximum error is +- MAXJSAMPLE (or less with error limiting);
        * this sets the required size of the range_limit array.
        */
-      cur0 += GETJSAMPLE(inptr[0]);
-      cur1 += GETJSAMPLE(inptr[1]);
-      cur2 += GETJSAMPLE(inptr[2]);
-      cur0 = GETJSAMPLE(range_limit[cur0]);
-      cur1 = GETJSAMPLE(range_limit[cur1]);
-      cur2 = GETJSAMPLE(range_limit[cur2]);
+      cur0 += inptr[0];
+      cur1 += inptr[1];
+      cur2 += inptr[2];
+      cur0 = range_limit[cur0];
+      cur1 = range_limit[cur1];
+      cur2 = range_limit[cur2];
       /* Index into the cache with adjusted pixel value */
       cachep =
         &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT];
@@ -1015,9 +1015,9 @@
         register int pixcode = *cachep - 1;
         *outptr = (JSAMPLE)pixcode;
         /* Compute representation error for this pixel */
-        cur0 -= GETJSAMPLE(colormap0[pixcode]);
-        cur1 -= GETJSAMPLE(colormap1[pixcode]);
-        cur2 -= GETJSAMPLE(colormap2[pixcode]);
+        cur0 -= colormap0[pixcode];
+        cur1 -= colormap1[pixcode];
+        cur2 -= colormap2[pixcode];
       }
       /* Compute error fractions to be propagated to adjacent pixels.
        * Add these into the running sums, and simultaneously shift the
@@ -1145,7 +1145,7 @@
   int i;
 
   /* Only F-S dithering or no dithering is supported. */
-  /* If user asks for ordered dither, give him F-S. */
+  /* If user asks for ordered dither, give them F-S. */
   if (cinfo->dither_mode != JDITHER_NONE)
     cinfo->dither_mode = JDITHER_FS;
 
@@ -1263,7 +1263,7 @@
     cquantize->sv_colormap = NULL;
 
   /* Only F-S dithering or no dithering is supported. */
-  /* If user asks for ordered dither, give him F-S. */
+  /* If user asks for ordered dither, give them F-S. */
   if (cinfo->dither_mode != JDITHER_NONE)
     cinfo->dither_mode = JDITHER_FS;
 
diff --git a/src/third_party/libjpeg-turbo/jsimd.h b/src/third_party/libjpeg-turbo/jsimd.h
index 51e2b8c..6c20365 100644
--- a/src/third_party/libjpeg-turbo/jsimd.h
+++ b/src/third_party/libjpeg-turbo/jsimd.h
@@ -4,6 +4,7 @@
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  * Copyright (C) 2011, 2014, D. R. Commander.
  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
+ * Copyright (C) 2020, Arm Limited.
  *
  * Based on the x86 SIMD extension for IJG JPEG library,
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -75,6 +76,7 @@
 
 EXTERN(int) jsimd_can_h2v2_fancy_upsample(void);
 EXTERN(int) jsimd_can_h2v1_fancy_upsample(void);
+EXTERN(int) jsimd_can_h1v2_fancy_upsample(void);
 
 EXTERN(void) jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,
                                        jpeg_component_info *compptr,
@@ -84,6 +86,10 @@
                                        jpeg_component_info *compptr,
                                        JSAMPARRAY input_data,
                                        JSAMPARRAY *output_data_ptr);
+EXTERN(void) jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo,
+                                       jpeg_component_info *compptr,
+                                       JSAMPARRAY input_data,
+                                       JSAMPARRAY *output_data_ptr);
 
 EXTERN(int) jsimd_can_h2v2_merged_upsample(void);
 EXTERN(int) jsimd_can_h2v1_merged_upsample(void);
diff --git a/src/third_party/libjpeg-turbo/jsimd_none.c b/src/third_party/libjpeg-turbo/jsimd_none.c
index 3cb6c80..5b38a9f 100644
--- a/src/third_party/libjpeg-turbo/jsimd_none.c
+++ b/src/third_party/libjpeg-turbo/jsimd_none.c
@@ -4,6 +4,7 @@
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  * Copyright (C) 2009-2011, 2014, D. R. Commander.
  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
+ * Copyright (C) 2020, Arm Limited.
  *
  * Based on the x86 SIMD extension for IJG JPEG library,
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -169,6 +170,12 @@
   return 0;
 }
 
+GLOBAL(int)
+jsimd_can_h1v2_fancy_upsample(void)
+{
+  return 0;
+}
+
 GLOBAL(void)
 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
@@ -181,6 +188,12 @@
 {
 }
 
+GLOBAL(void)
+jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
+                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
+{
+}
+
 GLOBAL(int)
 jsimd_can_h2v2_merged_upsample(void)
 {
diff --git a/src/third_party/libjpeg-turbo/jversion.h b/src/third_party/libjpeg-turbo/jversion.h
index 2039f44..2ab534a 100644
--- a/src/third_party/libjpeg-turbo/jversion.h
+++ b/src/third_party/libjpeg-turbo/jversion.h
@@ -2,9 +2,9 @@
  * jversion.h
  *
  * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2012-2018, D. R. Commander.
+ * Copyright (C) 2010, 2012-2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -30,23 +30,25 @@
  * NOTE: It is our convention to place the authors in the following order:
  * - libjpeg-turbo authors (2009-) in descending order of the date of their
  *   most recent contribution to the project, then in ascending order of the
- *   date of their first contribution to the project
+ *   date of their first contribution to the project, then in alphabetical
+ *   order
  * - Upstream authors in descending order of the date of the first inclusion of
  *   their code
  */
 
 #define JCOPYRIGHT \
-  "Copyright (C) 2009-2018 D. R. Commander\n" \
-  "Copyright (C) 2011-2016 Siarhei Siamashka\n" \
+  "Copyright (C) 2009-2021 D. R. Commander\n" \
+  "Copyright (C) 2015, 2020 Google, Inc.\n" \
+  "Copyright (C) 2019-2020 Arm Limited\n" \
   "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
+  "Copyright (C) 2011-2016 Siarhei Siamashka\n" \
   "Copyright (C) 2015 Intel Corporation\n" \
-  "Copyright (C) 2015 Google, Inc.\n" \
+  "Copyright (C) 2013-2014 Linaro Limited\n" \
   "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
-  "Copyright (C) 2013 Linaro Limited\n" \
+  "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
   "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
-  "Copyright (C) 2009 Pierre Ossman for Cendio AB\n" \
   "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
-  "Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding"
+  "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
 
 #define JCOPYRIGHT_SHORT \
-  "Copyright (C) 1991-2018 The libjpeg-turbo Project and many others"
+  "Copyright (C) 1991-2021 The libjpeg-turbo Project and many others"
diff --git a/src/third_party/libjpeg-turbo/libjpeg.gyp b/src/third_party/libjpeg-turbo/libjpeg.gyp
index 7225beb..2c9d00c 100644
--- a/src/third_party/libjpeg-turbo/libjpeg.gyp
+++ b/src/third_party/libjpeg-turbo/libjpeg.gyp
@@ -80,6 +80,7 @@
         'jmemnobs.c',
         'jmemsys.h',
         'jmorecfg.h',
+        'jpeg_nbits_table.c',
         'jpegint.h',
         'jpeglib.h',
         'jpeglibmangler.h',
@@ -102,17 +103,6 @@
         #'jdatadst.c',
       ],
       'conditions': [
-        # arm processor specific optimizations.
-        ['target_arch == "arm" and arm_neon == 1', {
-          'sources!': [
-            '<@(no_simd_files)'
-          ],
-          'sources': [
-            'simd/arm/jsimd.c',
-            'simd/arm/jsimd_neon.S',
-            'simd/jsimd.h',
-          ],
-        }],
         # x86_64 specific optimizations.
         ['<(yasm_exists) == 1 and target_arch == "x64"', {
           'sources!': [
diff --git a/src/third_party/libjpeg-turbo/libjpeg.txt b/src/third_party/libjpeg-turbo/libjpeg.txt
index 7e2341c..3c680b5 100644
--- a/src/third_party/libjpeg-turbo/libjpeg.txt
+++ b/src/third_party/libjpeg-turbo/libjpeg.txt
@@ -3,7 +3,7 @@
 This file was part of the Independent JPEG Group's software:
 Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
 libjpeg-turbo Modifications:
-Copyright (C) 2010, 2014-2017, D. R. Commander.
+Copyright (C) 2010, 2014-2018, 2020, D. R. Commander.
 Copyright (C) 2015, Google, Inc.
 For conditions of distribution and use, see the accompanying README.ijg file.
 
@@ -388,13 +388,13 @@
 just one or a few scanlines at a time.  The expected format for the passed
 data is discussed under "Data formats", above.
 
-Image data should be written in top-to-bottom scanline order.  The JPEG spec
-contains some weasel wording about how top and bottom are application-defined
-terms (a curious interpretation of the English language...) but if you want
-your files to be compatible with everyone else's, you WILL use top-to-bottom
-order.  If the source data must be read in bottom-to-top order, you can use
-the JPEG library's virtual array mechanism to invert the data efficiently.
-Examples of this can be found in the sample application cjpeg.
+Image data should be written in top-to-bottom scanline order.
+Rec. ITU-T T.81 | ISO/IEC 10918-1 says, "Applications determine which edges of
+a source image are defined as top, bottom, left, and right."  However, if you
+want your files to be compatible with everyone else's, then top-to-bottom order
+must be used.  If the source data must be read in bottom-to-top order, then you
+can use the JPEG library's virtual array mechanism to invert the data
+efficiently.  Examples of this can be found in the sample application cjpeg.
 
 The library maintains a count of the number of scanlines written so far
 in the next_scanline field of the JPEG object.  Usually you can just use
@@ -750,7 +750,9 @@
 
 Suspending data sources are not supported by this function.  Calling
 jpeg_skip_scanlines() with a suspending data source will result in undefined
-behavior.
+behavior.  Two-pass color quantization is also not supported by this function.
+Calling jpeg_skip_scanlines() with two-pass color quantization enabled will
+result in an error.
 
 jpeg_skip_scanlines() will not allow skipping past the bottom of the image.  If
 the value of num_lines is large enough to skip past the bottom of the image,
@@ -917,7 +919,8 @@
 jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
                          boolean force_baseline)
         Same as jpeg_set_quality() except that the generated tables are the
-        sample tables given in the JPEC spec section K.1, multiplied by the
+        sample tables given in Annex K (Clause K.1) of
+        Rec. ITU-T T.81 (1992) | ISO/IEC 10918-1:1994, multiplied by the
         specified scale factor (which is expressed as a percentage; thus
         scale_factor = 100 reproduces the spec's tables).  Note that larger
         scale factors give lower quality.  This entry point is useful for
@@ -966,30 +969,38 @@
 
 J_DCT_METHOD dct_method
         Selects the algorithm used for the DCT step.  Choices are:
-                JDCT_ISLOW: slow but accurate integer algorithm
-                JDCT_IFAST: faster, less accurate integer method
-                JDCT_FLOAT: floating-point method
+                JDCT_ISLOW: accurate integer method
+                JDCT_IFAST: less accurate integer method [legacy feature]
+                JDCT_FLOAT: floating-point method [legacy feature]
                 JDCT_DEFAULT: default method (normally JDCT_ISLOW)
                 JDCT_FASTEST: fastest method (normally JDCT_IFAST)
-        In libjpeg-turbo, JDCT_IFAST is generally about 5-15% faster than
-        JDCT_ISLOW when using the x86/x86-64 SIMD extensions (results may vary
-        with other SIMD implementations, or when using libjpeg-turbo without
-        SIMD extensions.)  For quality levels of 90 and below, there should be
-        little or no perceptible difference between the two algorithms.  For
-        quality levels above 90, however, the difference between JDCT_IFAST and
+        When the Independent JPEG Group's software was first released in 1991,
+        the compression time for a 1-megapixel JPEG image on a mainstream PC
+        was measured in minutes.  Thus, JDCT_IFAST provided noticeable
+        performance benefits.  On modern CPUs running libjpeg-turbo, however,
+        the compression time for a 1-megapixel JPEG image is measured in
+        milliseconds, and thus the performance benefits of JDCT_IFAST are much
+        less noticeable.  On modern x86/x86-64 CPUs that support AVX2
+        instructions, JDCT_IFAST and JDCT_ISLOW have similar performance.  On
+        other types of CPUs, JDCT_IFAST is generally about 5-15% faster than
+        JDCT_ISLOW.
+
+        For quality levels of 90 and below, there should be little or no
+        perceptible quality difference between the two algorithms.  For quality
+        levels above 90, however, the difference between JDCT_IFAST and
         JDCT_ISLOW becomes more pronounced.  With quality=97, for instance,
-        JDCT_IFAST incurs generally about a 1-3 dB loss (in PSNR) relative to
+        JDCT_IFAST incurs generally about a 1-3 dB loss in PSNR relative to
         JDCT_ISLOW, but this can be larger for some images.  Do not use
         JDCT_IFAST with quality levels above 97.  The algorithm often
         degenerates at quality=98 and above and can actually produce a more
         lossy image than if lower quality levels had been used.  Also, in
         libjpeg-turbo, JDCT_IFAST is not fully accelerated for quality levels
-        above 97, so it will be slower than JDCT_ISLOW.  JDCT_FLOAT is mainly a
-        legacy feature.  It does not produce significantly more accurate
-        results than the ISLOW method, and it is much slower.  The FLOAT method
-        may also give different results on different machines due to varying
-        roundoff behavior, whereas the integer methods should give the same
-        results on all machines.
+        above 97, so it will be slower than JDCT_ISLOW.
+
+        JDCT_FLOAT does not produce significantly more accurate results than
+        JDCT_ISLOW, and it is much slower.  JDCT_FLOAT may also give different
+        results on different machines due to varying roundoff behavior, whereas
+        the integer methods should give the same results on all machines.
 
 J_COLOR_SPACE jpeg_color_space
 int num_components
@@ -1267,31 +1278,39 @@
 
 J_DCT_METHOD dct_method
         Selects the algorithm used for the DCT step.  Choices are:
-                JDCT_ISLOW: slow but accurate integer algorithm
-                JDCT_IFAST: faster, less accurate integer method
-                JDCT_FLOAT: floating-point method
+                JDCT_ISLOW: accurate integer method
+                JDCT_IFAST: less accurate integer method [legacy feature]
+                JDCT_FLOAT: floating-point method [legacy feature]
                 JDCT_DEFAULT: default method (normally JDCT_ISLOW)
                 JDCT_FASTEST: fastest method (normally JDCT_IFAST)
-        In libjpeg-turbo, JDCT_IFAST is generally about 5-15% faster than
-        JDCT_ISLOW when using the x86/x86-64 SIMD extensions (results may vary
-        with other SIMD implementations, or when using libjpeg-turbo without
-        SIMD extensions.)  If the JPEG image was compressed using a quality
-        level of 85 or below, then there should be little or no perceptible
-        difference between the two algorithms.  When decompressing images that
-        were compressed using quality levels above 85, however, the difference
+        When the Independent JPEG Group's software was first released in 1991,
+        the decompression time for a 1-megapixel JPEG image on a mainstream PC
+        was measured in minutes.  Thus, JDCT_IFAST provided noticeable
+        performance benefits.  On modern CPUs running libjpeg-turbo, however,
+        the decompression time for a 1-megapixel JPEG image is measured in
+        milliseconds, and thus the performance benefits of JDCT_IFAST are much
+        less noticeable.  On modern x86/x86-64 CPUs that support AVX2
+        instructions, JDCT_IFAST and JDCT_ISLOW have similar performance.  On
+        other types of CPUs, JDCT_IFAST is generally about 5-15% faster than
+        JDCT_ISLOW.
+
+        If the JPEG image was compressed using a quality level of 85 or below,
+        then there should be little or no perceptible quality difference
+        between the two algorithms.  When decompressing images that were
+        compressed using quality levels above 85, however, the difference
         between JDCT_IFAST and JDCT_ISLOW becomes more pronounced.  With images
         compressed using quality=97, for instance, JDCT_IFAST incurs generally
-        about a 4-6 dB loss (in PSNR) relative to JDCT_ISLOW, but this can be
+        about a 4-6 dB loss in PSNR relative to JDCT_ISLOW, but this can be
         larger for some images.  If you can avoid it, do not use JDCT_IFAST
         when decompressing images that were compressed using quality levels
         above 97.  The algorithm often degenerates for such images and can
         actually produce a more lossy output image than if the JPEG image had
-        been compressed using lower quality levels.  JDCT_FLOAT is mainly a
-        legacy feature.  It does not produce significantly more accurate
-        results than the ISLOW method, and it is much slower.  The FLOAT method
-        may also give different results on different machines due to varying
-        roundoff behavior, whereas the integer methods should give the same
-        results on all machines.
+        been compressed using lower quality levels.
+
+        JDCT_FLOAT does not produce significantly more accurate results than
+        JDCT_ISLOW, and it is much slower.  JDCT_FLOAT may also give different
+        results on different machines due to varying roundoff behavior, whereas
+        the integer methods should give the same results on all machines.
 
 boolean do_fancy_upsampling
         If TRUE, do careful upsampling of chroma components.  If FALSE,
diff --git a/src/third_party/libjpeg-turbo/md5/CMakeLists.txt b/src/third_party/libjpeg-turbo/md5/CMakeLists.txt
deleted file mode 100644
index 526ef08..0000000
--- a/src/third_party/libjpeg-turbo/md5/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_executable(md5cmp md5cmp.c md5.c md5hl.c)
diff --git a/src/third_party/libjpeg-turbo/md5/md5cmp.c b/src/third_party/libjpeg-turbo/md5/md5cmp.c
deleted file mode 100644
index 42b94ce..0000000
--- a/src/third_party/libjpeg-turbo/md5/md5cmp.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C)2013, 2016 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "./md5.h"
-#include "../tjutil.h"
-
-int main(int argc, char *argv[])
-{
-  char *md5sum = NULL, buf[65];
-
-  if (argc < 3) {
-    fprintf(stderr, "USAGE: %s <correct MD5 sum> <file>\n", argv[0]);
-    return -1;
-  }
-
-  if (strlen(argv[1]) != 32)
-    fprintf(stderr, "WARNING: MD5 hash size is wrong.\n");
-
-  md5sum = MD5File(argv[2], buf);
-  if (!md5sum) {
-    perror("Could not obtain MD5 sum");
-    return -1;
-  }
-
-  if (!strcasecmp(md5sum, argv[1])) {
-    fprintf(stderr, "%s: OK\n", argv[2]);
-    return 0;
-  } else {
-    fprintf(stderr, "%s: FAILED.  Checksum is %s\n", argv[2], md5sum);
-    return -1;
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/md5/md5hl.c b/src/third_party/libjpeg-turbo/md5/md5hl.c
index ecd2e23..8a4a762 100644
--- a/src/third_party/libjpeg-turbo/md5/md5hl.c
+++ b/src/third_party/libjpeg-turbo/md5/md5hl.c
@@ -6,7 +6,7 @@
  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
  * ----------------------------------------------------------------------------
  * libjpeg-turbo Modifications:
- * Copyright (C)2016, 2018 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2016, 2018-2019 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -56,7 +56,7 @@
 
 #include "./md5.h"
 
-char *MD5End(MD5_CTX *ctx, char *buf)
+static char *MD5End(MD5_CTX *ctx, char *buf)
 {
   int i;
   unsigned char digest[LENGTH];
@@ -89,7 +89,7 @@
   off_t n;
 
   MD5Init(&ctx);
-#if _WIN32
+#ifdef _WIN32
   f = _open(filename, O_RDONLY | O_BINARY);
 #else
   f = open(filename, O_RDONLY);
@@ -123,12 +123,3 @@
     return 0;
   return (MD5End(&ctx, buf));
 }
-
-char *MD5Data(const void *data, unsigned int len, char *buf)
-{
-  MD5_CTX ctx;
-
-  MD5Init(&ctx);
-  MD5Update(&ctx, (unsigned char *)data, len);
-  return (MD5End(&ctx, buf));
-}
diff --git a/src/third_party/libjpeg-turbo/rdbmp.c b/src/third_party/libjpeg-turbo/rdbmp.c
index fcabbb1..358a026 100644
--- a/src/third_party/libjpeg-turbo/rdbmp.c
+++ b/src/third_party/libjpeg-turbo/rdbmp.c
@@ -3,16 +3,16 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1994-1996, Thomas G. Lane.
- * Modified 2009-2010 by Guido Vollbeding.
+ * Modified 2009-2017 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
  * Modified 2011 by Siarhei Siamashka.
- * Copyright (C) 2015, 2017, D. R. Commander.
+ * Copyright (C) 2015, 2017-2018, 2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
  * This file contains routines to read input images in Microsoft "BMP"
  * format (MS Windows 3.x, OS/2 1.x, and OS/2 2.x flavors).
- * Currently, only 8-bit and 24-bit images are supported, not 1-bit or
+ * Currently, only 8-, 24-, and 32-bit images are supported, not 1-bit or
  * 4-bit (feeding such low-depth images into JPEG would be silly anyway).
  * Also, we don't support RLE-compressed files.
  *
@@ -34,18 +34,8 @@
 
 /* Macros to deal with unsigned chars as efficiently as compiler allows */
 
-#ifdef HAVE_UNSIGNED_CHAR
 typedef unsigned char U_CHAR;
 #define UCH(x)  ((int)(x))
-#else /* !HAVE_UNSIGNED_CHAR */
-#ifdef __CHAR_UNSIGNED__
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x))
-#else
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x) & 0xFF)
-#endif
-#endif /* HAVE_UNSIGNED_CHAR */
 
 
 #define ReadOK(file, buffer, len) \
@@ -71,7 +61,8 @@
   JDIMENSION source_row;        /* Current source row number */
   JDIMENSION row_width;         /* Physical width of scanlines in file */
 
-  int bits_per_pixel;           /* remembers 8- or 24-bit format */
+  int bits_per_pixel;           /* remembers 8-, 24-, or 32-bit format */
+  int cmap_length;              /* colormap length */
 
   boolean use_inversion_array;  /* TRUE = preload the whole image, which is
                                    stored in bottom-up order, and feed it to
@@ -155,6 +146,7 @@
 {
   bmp_source_ptr source = (bmp_source_ptr)sinfo;
   register JSAMPARRAY colormap = source->colormap;
+  int cmaplen = source->cmap_length;
   JSAMPARRAY image_ptr;
   register int t;
   register JSAMPROW inptr, outptr;
@@ -177,12 +169,16 @@
   outptr = source->pub.buffer[0];
   if (cinfo->in_color_space == JCS_GRAYSCALE) {
     for (col = cinfo->image_width; col > 0; col--) {
-      t = GETJSAMPLE(*inptr++);
+      t = *inptr++;
+      if (t >= cmaplen)
+        ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
       *outptr++ = colormap[0][t];
     }
   } else if (cinfo->in_color_space == JCS_CMYK) {
     for (col = cinfo->image_width; col > 0; col--) {
-      t = GETJSAMPLE(*inptr++);
+      t = *inptr++;
+      if (t >= cmaplen)
+        ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
       rgb_to_cmyk(colormap[0][t], colormap[1][t], colormap[2][t], outptr,
                   outptr + 1, outptr + 2, outptr + 3);
       outptr += 4;
@@ -196,7 +192,9 @@
 
     if (aindex >= 0) {
       for (col = cinfo->image_width; col > 0; col--) {
-        t = GETJSAMPLE(*inptr++);
+        t = *inptr++;
+        if (t >= cmaplen)
+          ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
         outptr[rindex] = colormap[0][t];
         outptr[gindex] = colormap[1][t];
         outptr[bindex] = colormap[2][t];
@@ -205,7 +203,9 @@
       }
     } else {
       for (col = cinfo->image_width; col > 0; col--) {
-        t = GETJSAMPLE(*inptr++);
+        t = *inptr++;
+        if (t >= cmaplen)
+          ERREXIT(cinfo, JERR_BMP_OUTOFRANGE);
         outptr[rindex] = colormap[0][t];
         outptr[gindex] = colormap[1][t];
         outptr[bindex] = colormap[2][t];
@@ -248,7 +248,6 @@
     MEMCOPY(outptr, inptr, source->row_width);
   } else if (cinfo->in_color_space == JCS_CMYK) {
     for (col = cinfo->image_width; col > 0; col--) {
-      /* can omit GETJSAMPLE() safely */
       JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
       rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
       outptr += 4;
@@ -262,7 +261,7 @@
 
     if (aindex >= 0) {
       for (col = cinfo->image_width; col > 0; col--) {
-        outptr[bindex] = *inptr++;      /* can omit GETJSAMPLE() safely */
+        outptr[bindex] = *inptr++;
         outptr[gindex] = *inptr++;
         outptr[rindex] = *inptr++;
         outptr[aindex] = 0xFF;
@@ -270,7 +269,7 @@
       }
     } else {
       for (col = cinfo->image_width; col > 0; col--) {
-        outptr[bindex] = *inptr++;      /* can omit GETJSAMPLE() safely */
+        outptr[bindex] = *inptr++;
         outptr[gindex] = *inptr++;
         outptr[rindex] = *inptr++;
         outptr += ps;
@@ -313,7 +312,6 @@
     MEMCOPY(outptr, inptr, source->row_width);
   } else if (cinfo->in_color_space == JCS_CMYK) {
     for (col = cinfo->image_width; col > 0; col--) {
-      /* can omit GETJSAMPLE() safely */
       JSAMPLE b = *inptr++, g = *inptr++, r = *inptr++;
       rgb_to_cmyk(r, g, b, outptr, outptr + 1, outptr + 2, outptr + 3);
       inptr++;                          /* skip the 4th byte (Alpha channel) */
@@ -328,7 +326,7 @@
 
     if (aindex >= 0) {
       for (col = cinfo->image_width; col > 0; col--) {
-        outptr[bindex] = *inptr++;      /* can omit GETJSAMPLE() safely */
+        outptr[bindex] = *inptr++;
         outptr[gindex] = *inptr++;
         outptr[rindex] = *inptr++;
         outptr[aindex] = *inptr++;
@@ -336,7 +334,7 @@
       }
     } else {
       for (col = cinfo->image_width; col > 0; col--) {
-        outptr[bindex] = *inptr++;      /* can omit GETJSAMPLE() safely */
+        outptr[bindex] = *inptr++;
         outptr[gindex] = *inptr++;
         outptr[rindex] = *inptr++;
         inptr++;                        /* skip the 4th byte (Alpha channel) */
@@ -426,14 +424,14 @@
    (((unsigned int)UCH(array[offset + 2])) << 16) + \
    (((unsigned int)UCH(array[offset + 3])) << 24))
 
-  unsigned int bfOffBits;
-  unsigned int headerSize;
+  int bfOffBits;
+  int headerSize;
   int biWidth;
   int biHeight;
   unsigned short biPlanes;
   unsigned int biCompression;
   int biXPelsPerMeter, biYPelsPerMeter;
-  unsigned int biClrUsed = 0;
+  int biClrUsed = 0;
   int mapentrysize = 0;         /* 0 indicates no colormap */
   int bPad;
   JDIMENSION row_width = 0;
@@ -452,7 +450,7 @@
   if (!ReadOK(source->pub.input_file, bmpinfoheader, 4))
     ERREXIT(cinfo, JERR_INPUT_EOF);
   headerSize = GET_4B(bmpinfoheader, 0);
-  if (headerSize < 12 || headerSize > 64)
+  if (headerSize < 12 || headerSize > 64 || (headerSize + 14) > bfOffBits)
     ERREXIT(cinfo, JERR_BMP_BADHEADER);
   if (!ReadOK(source->pub.input_file, bmpinfoheader + 4, headerSize - 4))
     ERREXIT(cinfo, JERR_INPUT_EOF);
@@ -471,7 +469,9 @@
       TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, biWidth, biHeight);
       break;
     case 24:                    /* RGB image */
-      TRACEMS2(cinfo, 1, JTRC_BMP_OS2, biWidth, biHeight);
+    case 32:                    /* RGB image + Alpha channel */
+      TRACEMS3(cinfo, 1, JTRC_BMP_OS2, biWidth, biHeight,
+               source->bits_per_pixel);
       break;
     default:
       ERREXIT(cinfo, JERR_BMP_BADDEPTH);
@@ -498,10 +498,8 @@
       TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, biWidth, biHeight);
       break;
     case 24:                    /* RGB image */
-      TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
-      break;
     case 32:                    /* RGB image + Alpha channel */
-      TRACEMS2(cinfo, 1, JTRC_BMP, biWidth, biHeight);
+      TRACEMS3(cinfo, 1, JTRC_BMP, biWidth, biHeight, source->bits_per_pixel);
       break;
     default:
       ERREXIT(cinfo, JERR_BMP_BADDEPTH);
@@ -524,6 +522,11 @@
 
   if (biWidth <= 0 || biHeight <= 0)
     ERREXIT(cinfo, JERR_BMP_EMPTY);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  if (sinfo->max_pixels &&
+      (unsigned long long)biWidth * biHeight > sinfo->max_pixels)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+#endif
   if (biPlanes != 1)
     ERREXIT(cinfo, JERR_BMP_BADPLANES);
 
@@ -539,6 +542,7 @@
     /* Allocate space to store the colormap */
     source->colormap = (*cinfo->mem->alloc_sarray)
       ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)biClrUsed, (JDIMENSION)3);
+    source->cmap_length = (int)biClrUsed;
     /* and read it from the file */
     read_colormap(source, (int)biClrUsed, mapentrysize);
     /* account for size of colormap */
@@ -576,7 +580,9 @@
       cinfo->input_components = 4;
     else
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
-    row_width = (JDIMENSION)(biWidth * 3);
+    if ((unsigned long long)biWidth * 3ULL > 0xFFFFFFFFULL)
+      ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+    row_width = (JDIMENSION)biWidth * 3;
     break;
   case 32:
     if (cinfo->in_color_space == JCS_UNKNOWN)
@@ -587,7 +593,9 @@
       cinfo->input_components = 4;
     else
       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
-    row_width = (JDIMENSION)(biWidth * 4);
+    if ((unsigned long long)biWidth * 4ULL > 0xFFFFFFFFULL)
+      ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+    row_width = (JDIMENSION)biWidth * 4;
     break;
   default:
     ERREXIT(cinfo, JERR_BMP_BADDEPTH);
@@ -623,10 +631,16 @@
     }
   }
 
+  /* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
+     value of the JDIMENSION type.  This is only a danger with BMP files, since
+     their width and height fields are 32-bit integers. */
+  if ((unsigned long long)biWidth *
+      (unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
   /* Allocate one-row buffer for returned data */
   source->pub.buffer = (*cinfo->mem->alloc_sarray)
     ((j_common_ptr)cinfo, JPOOL_IMAGE,
-     (JDIMENSION)(biWidth * cinfo->input_components), (JDIMENSION)1);
+     (JDIMENSION)biWidth * (JDIMENSION)cinfo->input_components, (JDIMENSION)1);
   source->pub.buffer_height = 1;
 
   cinfo->data_precision = 8;
@@ -663,6 +677,9 @@
   /* Fill in method ptrs, except get_pixel_rows which start_input sets */
   source->pub.start_input = start_input_bmp;
   source->pub.finish_input = finish_input_bmp;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  source->pub.max_pixels = 0;
+#endif
 
   source->use_inversion_array = use_inversion_array;
 
diff --git a/src/third_party/libjpeg-turbo/rdcolmap.c b/src/third_party/libjpeg-turbo/rdcolmap.c
index cbbef59..d2ed95c 100644
--- a/src/third_party/libjpeg-turbo/rdcolmap.c
+++ b/src/third_party/libjpeg-turbo/rdcolmap.c
@@ -54,9 +54,8 @@
 
   /* Check for duplicate color. */
   for (index = 0; index < ncolors; index++) {
-    if (GETJSAMPLE(colormap0[index]) == R &&
-        GETJSAMPLE(colormap1[index]) == G &&
-        GETJSAMPLE(colormap2[index]) == B)
+    if (colormap0[index] == R && colormap1[index] == G &&
+        colormap2[index] == B)
       return;                   /* color is already in map */
   }
 
diff --git a/src/third_party/libjpeg-turbo/rdgif.c b/src/third_party/libjpeg-turbo/rdgif.c
index ff9258d..c814c6b 100644
--- a/src/third_party/libjpeg-turbo/rdgif.c
+++ b/src/third_party/libjpeg-turbo/rdgif.c
@@ -1,29 +1,673 @@
 /*
  * rdgif.c
  *
+ * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
- * This file is part of the Independent JPEG Group's software.
+ * Modified 2019 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
  * This file contains routines to read input images in GIF format.
  *
- *****************************************************************************
- * NOTE: to avoid entanglements with Unisys' patent on LZW compression,      *
- * the ability to read GIF files has been removed from the IJG distribution. *
- * Sorry about that.                                                         *
- *****************************************************************************
- *
- * We are required to state that
- *    "The Graphics Interchange Format(c) is the Copyright property of
- *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
- *    CompuServe Incorporated."
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume input from
+ * an ordinary stdio stream.  They further assume that reading begins
+ * at the start of the file; start_input may need work if the
+ * user interface has already read some data (e.g., to determine that
+ * the file is indeed GIF format).
+ */
+
+/*
+ * This code is loosely based on giftoppm from the PBMPLUS distribution
+ * of Feb. 1991.  That file contains the following copyright notice:
+ * +-------------------------------------------------------------------+
+ * | Copyright 1990, David Koblas.                                     |
+ * |   Permission to use, copy, modify, and distribute this software   |
+ * |   and its documentation for any purpose and without fee is hereby |
+ * |   granted, provided that the above copyright notice appear in all |
+ * |   copies and that both that copyright notice and this permission  |
+ * |   notice appear in supporting documentation.  This software is    |
+ * |   provided "as is" without express or implied warranty.           |
+ * +-------------------------------------------------------------------+
  */
 
 #include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
 
 #ifdef GIF_SUPPORTED
 
+
+/* Macros to deal with unsigned chars as efficiently as compiler allows */
+
+typedef unsigned char U_CHAR;
+#define UCH(x)  ((int)(x))
+
+
+#define ReadOK(file, buffer, len) \
+  (JFREAD(file, buffer, len) == ((size_t)(len)))
+
+
+#define MAXCOLORMAPSIZE  256    /* max # of colors in a GIF colormap */
+#define NUMCOLORS        3      /* # of colors */
+#define CM_RED           0      /* color component numbers */
+#define CM_GREEN         1
+#define CM_BLUE          2
+
+#define MAX_LZW_BITS     12     /* maximum LZW code size */
+#define LZW_TABLE_SIZE   (1 << MAX_LZW_BITS) /* # of possible LZW symbols */
+
+/* Macros for extracting header data --- note we assume chars may be signed */
+
+#define LM_to_uint(array, offset) \
+  ((unsigned int)UCH(array[offset]) + \
+   (((unsigned int)UCH(array[offset + 1])) << 8))
+
+#define BitSet(byte, bit)       ((byte) & (bit))
+#define INTERLACE       0x40    /* mask for bit signifying interlaced image */
+#define COLORMAPFLAG    0x80    /* mask for bit signifying colormap presence */
+
+
+/*
+ * LZW decompression tables look like this:
+ *   symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
+ *   symbol_tail[K] = suffix byte   of any LZW symbol K (0..LZW_TABLE_SIZE-1)
+ * Note that entries 0..end_code of the above tables are not used,
+ * since those symbols represent raw bytes or special codes.
+ *
+ * The stack represents the not-yet-used expansion of the last LZW symbol.
+ * In the worst case, a symbol could expand to as many bytes as there are
+ * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
+ * (This is conservative since that number includes the raw-byte symbols.)
+ */
+
+
+/* Private version of data source object */
+
+typedef struct {
+  struct cjpeg_source_struct pub; /* public fields */
+
+  j_compress_ptr cinfo;         /* back link saves passing separate parm */
+
+  JSAMPARRAY colormap;          /* GIF colormap (converted to my format) */
+
+  /* State for GetCode and LZWReadByte */
+  U_CHAR code_buf[256 + 4];     /* current input data block */
+  int last_byte;                /* # of bytes in code_buf */
+  int last_bit;                 /* # of bits in code_buf */
+  int cur_bit;                  /* next bit index to read */
+  boolean first_time;           /* flags first call to GetCode */
+  boolean out_of_blocks;        /* TRUE if hit terminator data block */
+
+  int input_code_size;          /* codesize given in GIF file */
+  int clear_code, end_code;     /* values for Clear and End codes */
+
+  int code_size;                /* current actual code size */
+  int limit_code;               /* 2^code_size */
+  int max_code;                 /* first unused code value */
+
+  /* Private state for LZWReadByte */
+  int oldcode;                  /* previous LZW symbol */
+  int firstcode;                /* first byte of oldcode's expansion */
+
+  /* LZW symbol table and expansion stack */
+  UINT16 *symbol_head;          /* => table of prefix symbols */
+  UINT8  *symbol_tail;          /* => table of suffix bytes */
+  UINT8  *symbol_stack;         /* => stack for symbol expansions */
+  UINT8  *sp;                   /* stack pointer */
+
+  /* State for interlaced image processing */
+  boolean is_interlaced;        /* TRUE if have interlaced image */
+  jvirt_sarray_ptr interlaced_image; /* full image in interlaced order */
+  JDIMENSION cur_row_number;    /* need to know actual row number */
+  JDIMENSION pass2_offset;      /* # of pixel rows in pass 1 */
+  JDIMENSION pass3_offset;      /* # of pixel rows in passes 1&2 */
+  JDIMENSION pass4_offset;      /* # of pixel rows in passes 1,2,3 */
+} gif_source_struct;
+
+typedef gif_source_struct *gif_source_ptr;
+
+
+/* Forward declarations */
+METHODDEF(JDIMENSION) get_pixel_rows(j_compress_ptr cinfo,
+                                     cjpeg_source_ptr sinfo);
+METHODDEF(JDIMENSION) load_interlaced_image(j_compress_ptr cinfo,
+                                            cjpeg_source_ptr sinfo);
+METHODDEF(JDIMENSION) get_interlaced_row(j_compress_ptr cinfo,
+                                         cjpeg_source_ptr sinfo);
+
+
+LOCAL(int)
+ReadByte(gif_source_ptr sinfo)
+/* Read next byte from GIF file */
+{
+  register FILE *infile = sinfo->pub.input_file;
+  register int c;
+
+  if ((c = getc(infile)) == EOF)
+    ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
+  return c;
+}
+
+
+LOCAL(int)
+GetDataBlock(gif_source_ptr sinfo, U_CHAR *buf)
+/* Read a GIF data block, which has a leading count byte */
+/* A zero-length block marks the end of a data block sequence */
+{
+  int count;
+
+  count = ReadByte(sinfo);
+  if (count > 0) {
+    if (!ReadOK(sinfo->pub.input_file, buf, count))
+      ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
+  }
+  return count;
+}
+
+
+LOCAL(void)
+SkipDataBlocks(gif_source_ptr sinfo)
+/* Skip a series of data blocks, until a block terminator is found */
+{
+  U_CHAR buf[256];
+
+  while (GetDataBlock(sinfo, buf) > 0)
+    /* skip */;
+}
+
+
+LOCAL(void)
+ReInitLZW(gif_source_ptr sinfo)
+/* (Re)initialize LZW state; shared code for startup and Clear processing */
+{
+  sinfo->code_size = sinfo->input_code_size + 1;
+  sinfo->limit_code = sinfo->clear_code << 1;   /* 2^code_size */
+  sinfo->max_code = sinfo->clear_code + 2;      /* first unused code value */
+  sinfo->sp = sinfo->symbol_stack;              /* init stack to empty */
+}
+
+
+LOCAL(void)
+InitLZWCode(gif_source_ptr sinfo)
+/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
+{
+  /* GetCode initialization */
+  sinfo->last_byte = 2;         /* make safe to "recopy last two bytes" */
+  sinfo->code_buf[0] = 0;
+  sinfo->code_buf[1] = 0;
+  sinfo->last_bit = 0;          /* nothing in the buffer */
+  sinfo->cur_bit = 0;           /* force buffer load on first call */
+  sinfo->first_time = TRUE;
+  sinfo->out_of_blocks = FALSE;
+
+  /* LZWReadByte initialization: */
+  /* compute special code values (note that these do not change later) */
+  sinfo->clear_code = 1 << sinfo->input_code_size;
+  sinfo->end_code = sinfo->clear_code + 1;
+  ReInitLZW(sinfo);
+}
+
+
+LOCAL(int)
+GetCode(gif_source_ptr sinfo)
+/* Fetch the next code_size bits from the GIF data */
+/* We assume code_size is less than 16 */
+{
+  register int accum;
+  int offs, count;
+
+  while (sinfo->cur_bit + sinfo->code_size > sinfo->last_bit) {
+    /* Time to reload the buffer */
+    /* First time, share code with Clear case */
+    if (sinfo->first_time) {
+      sinfo->first_time = FALSE;
+      return sinfo->clear_code;
+    }
+    if (sinfo->out_of_blocks) {
+      WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
+      return sinfo->end_code;   /* fake something useful */
+    }
+    /* preserve last two bytes of what we have -- assume code_size <= 16 */
+    sinfo->code_buf[0] = sinfo->code_buf[sinfo->last_byte-2];
+    sinfo->code_buf[1] = sinfo->code_buf[sinfo->last_byte-1];
+    /* Load more bytes; set flag if we reach the terminator block */
+    if ((count = GetDataBlock(sinfo, &sinfo->code_buf[2])) == 0) {
+      sinfo->out_of_blocks = TRUE;
+      WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
+      return sinfo->end_code;   /* fake something useful */
+    }
+    /* Reset counters */
+    sinfo->cur_bit = (sinfo->cur_bit - sinfo->last_bit) + 16;
+    sinfo->last_byte = 2 + count;
+    sinfo->last_bit = sinfo->last_byte * 8;
+  }
+
+  /* Form up next 24 bits in accum */
+  offs = sinfo->cur_bit >> 3;   /* byte containing cur_bit */
+  accum = UCH(sinfo->code_buf[offs + 2]);
+  accum <<= 8;
+  accum |= UCH(sinfo->code_buf[offs + 1]);
+  accum <<= 8;
+  accum |= UCH(sinfo->code_buf[offs]);
+
+  /* Right-align cur_bit in accum, then mask off desired number of bits */
+  accum >>= (sinfo->cur_bit & 7);
+  sinfo->cur_bit += sinfo->code_size;
+  return accum & ((1 << sinfo->code_size) - 1);
+}
+
+
+LOCAL(int)
+LZWReadByte(gif_source_ptr sinfo)
+/* Read an LZW-compressed byte */
+{
+  register int code;            /* current working code */
+  int incode;                   /* saves actual input code */
+
+  /* If any codes are stacked from a previously read symbol, return them */
+  if (sinfo->sp > sinfo->symbol_stack)
+    return (int)(*(--sinfo->sp));
+
+  /* Time to read a new symbol */
+  code = GetCode(sinfo);
+
+  if (code == sinfo->clear_code) {
+    /* Reinit state, swallow any extra Clear codes, and */
+    /* return next code, which is expected to be a raw byte. */
+    ReInitLZW(sinfo);
+    do {
+      code = GetCode(sinfo);
+    } while (code == sinfo->clear_code);
+    if (code > sinfo->clear_code) { /* make sure it is a raw byte */
+      WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
+      code = 0;                 /* use something valid */
+    }
+    /* make firstcode, oldcode valid! */
+    sinfo->firstcode = sinfo->oldcode = code;
+    return code;
+  }
+
+  if (code == sinfo->end_code) {
+    /* Skip the rest of the image, unless GetCode already read terminator */
+    if (!sinfo->out_of_blocks) {
+      SkipDataBlocks(sinfo);
+      sinfo->out_of_blocks = TRUE;
+    }
+    /* Complain that there's not enough data */
+    WARNMS(sinfo->cinfo, JWRN_GIF_ENDCODE);
+    /* Pad data with 0's */
+    return 0;                   /* fake something usable */
+  }
+
+  /* Got normal raw byte or LZW symbol */
+  incode = code;                /* save for a moment */
+
+  if (code >= sinfo->max_code) { /* special case for not-yet-defined symbol */
+    /* code == max_code is OK; anything bigger is bad data */
+    if (code > sinfo->max_code) {
+      WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
+      incode = 0;               /* prevent creation of loops in symbol table */
+    }
+    /* this symbol will be defined as oldcode/firstcode */
+    *(sinfo->sp++) = (UINT8)sinfo->firstcode;
+    code = sinfo->oldcode;
+  }
+
+  /* If it's a symbol, expand it into the stack */
+  while (code >= sinfo->clear_code) {
+    *(sinfo->sp++) = sinfo->symbol_tail[code]; /* tail is a byte value */
+    code = sinfo->symbol_head[code]; /* head is another LZW symbol */
+  }
+  /* At this point code just represents a raw byte */
+  sinfo->firstcode = code;      /* save for possible future use */
+
+  /* If there's room in table... */
+  if ((code = sinfo->max_code) < LZW_TABLE_SIZE) {
+    /* Define a new symbol = prev sym + head of this sym's expansion */
+    sinfo->symbol_head[code] = (UINT16)sinfo->oldcode;
+    sinfo->symbol_tail[code] = (UINT8)sinfo->firstcode;
+    sinfo->max_code++;
+    /* Is it time to increase code_size? */
+    if (sinfo->max_code >= sinfo->limit_code &&
+        sinfo->code_size < MAX_LZW_BITS) {
+      sinfo->code_size++;
+      sinfo->limit_code <<= 1;  /* keep equal to 2^code_size */
+    }
+  }
+
+  sinfo->oldcode = incode;      /* save last input symbol for future use */
+  return sinfo->firstcode;      /* return first byte of symbol's expansion */
+}
+
+
+LOCAL(void)
+ReadColorMap(gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
+/* Read a GIF colormap */
+{
+  int i;
+
+  for (i = 0; i < cmaplen; i++) {
+#if BITS_IN_JSAMPLE == 8
+#define UPSCALE(x)  (x)
+#else
+#define UPSCALE(x)  ((x) << (BITS_IN_JSAMPLE - 8))
+#endif
+    cmap[CM_RED][i]   = (JSAMPLE)UPSCALE(ReadByte(sinfo));
+    cmap[CM_GREEN][i] = (JSAMPLE)UPSCALE(ReadByte(sinfo));
+    cmap[CM_BLUE][i]  = (JSAMPLE)UPSCALE(ReadByte(sinfo));
+  }
+}
+
+
+LOCAL(void)
+DoExtension(gif_source_ptr sinfo)
+/* Process an extension block */
+/* Currently we ignore 'em all */
+{
+  int extlabel;
+
+  /* Read extension label byte */
+  extlabel = ReadByte(sinfo);
+  TRACEMS1(sinfo->cinfo, 1, JTRC_GIF_EXTENSION, extlabel);
+  /* Skip the data block(s) associated with the extension */
+  SkipDataBlocks(sinfo);
+}
+
+
+/*
+ * Read the file header; return image size and component count.
+ */
+
+METHODDEF(void)
+start_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+{
+  gif_source_ptr source = (gif_source_ptr)sinfo;
+  U_CHAR hdrbuf[10];            /* workspace for reading control blocks */
+  unsigned int width, height;   /* image dimensions */
+  int colormaplen, aspectRatio;
+  int c;
+
+  /* Read and verify GIF Header */
+  if (!ReadOK(source->pub.input_file, hdrbuf, 6))
+    ERREXIT(cinfo, JERR_GIF_NOT);
+  if (hdrbuf[0] != 'G' || hdrbuf[1] != 'I' || hdrbuf[2] != 'F')
+    ERREXIT(cinfo, JERR_GIF_NOT);
+  /* Check for expected version numbers.
+   * If unknown version, give warning and try to process anyway;
+   * this is per recommendation in GIF89a standard.
+   */
+  if ((hdrbuf[3] != '8' || hdrbuf[4] != '7' || hdrbuf[5] != 'a') &&
+      (hdrbuf[3] != '8' || hdrbuf[4] != '9' || hdrbuf[5] != 'a'))
+    TRACEMS3(cinfo, 1, JTRC_GIF_BADVERSION, hdrbuf[3], hdrbuf[4], hdrbuf[5]);
+
+  /* Read and decipher Logical Screen Descriptor */
+  if (!ReadOK(source->pub.input_file, hdrbuf, 7))
+    ERREXIT(cinfo, JERR_INPUT_EOF);
+  width = LM_to_uint(hdrbuf, 0);
+  height = LM_to_uint(hdrbuf, 2);
+  if (width == 0 || height == 0)
+    ERREXIT(cinfo, JERR_GIF_EMPTY);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  if (sinfo->max_pixels &&
+      (unsigned long long)width * height > sinfo->max_pixels)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+#endif
+  /* we ignore the color resolution, sort flag, and background color index */
+  aspectRatio = UCH(hdrbuf[6]);
+  if (aspectRatio != 0 && aspectRatio != 49)
+    TRACEMS(cinfo, 1, JTRC_GIF_NONSQUARE);
+
+  /* Allocate space to store the colormap */
+  source->colormap = (*cinfo->mem->alloc_sarray)
+    ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)MAXCOLORMAPSIZE,
+     (JDIMENSION)NUMCOLORS);
+  colormaplen = 0;              /* indicate initialization */
+
+  /* Read global colormap if header indicates it is present */
+  if (BitSet(hdrbuf[4], COLORMAPFLAG)) {
+    colormaplen = 2 << (hdrbuf[4] & 0x07);
+    ReadColorMap(source, colormaplen, source->colormap);
+  }
+
+  /* Scan until we reach start of desired image.
+   * We don't currently support skipping images, but could add it easily.
+   */
+  for (;;) {
+    c = ReadByte(source);
+
+    if (c == ';')               /* GIF terminator?? */
+      ERREXIT(cinfo, JERR_GIF_IMAGENOTFOUND);
+
+    if (c == '!') {             /* Extension */
+      DoExtension(source);
+      continue;
+    }
+
+    if (c != ',') {             /* Not an image separator? */
+      WARNMS1(cinfo, JWRN_GIF_CHAR, c);
+      continue;
+    }
+
+    /* Read and decipher Local Image Descriptor */
+    if (!ReadOK(source->pub.input_file, hdrbuf, 9))
+      ERREXIT(cinfo, JERR_INPUT_EOF);
+    /* we ignore top/left position info, also sort flag */
+    width = LM_to_uint(hdrbuf, 4);
+    height = LM_to_uint(hdrbuf, 6);
+    if (width == 0 || height == 0)
+      ERREXIT(cinfo, JERR_GIF_EMPTY);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    if (sinfo->max_pixels &&
+        (unsigned long long)width * height > sinfo->max_pixels)
+      ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+#endif
+    source->is_interlaced = (BitSet(hdrbuf[8], INTERLACE) != 0);
+
+    /* Read local colormap if header indicates it is present */
+    /* Note: if we wanted to support skipping images, */
+    /* we'd need to skip rather than read colormap for ignored images */
+    if (BitSet(hdrbuf[8], COLORMAPFLAG)) {
+      colormaplen = 2 << (hdrbuf[8] & 0x07);
+      ReadColorMap(source, colormaplen, source->colormap);
+    }
+
+    source->input_code_size = ReadByte(source); /* get min-code-size byte */
+    if (source->input_code_size < 2 || source->input_code_size > 8)
+      ERREXIT1(cinfo, JERR_GIF_CODESIZE, source->input_code_size);
+
+    /* Reached desired image, so break out of loop */
+    /* If we wanted to skip this image, */
+    /* we'd call SkipDataBlocks and then continue the loop */
+    break;
+  }
+
+  /* Prepare to read selected image: first initialize LZW decompressor */
+  source->symbol_head = (UINT16 *)
+    (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                LZW_TABLE_SIZE * sizeof(UINT16));
+  source->symbol_tail = (UINT8 *)
+    (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                LZW_TABLE_SIZE * sizeof(UINT8));
+  source->symbol_stack = (UINT8 *)
+    (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                LZW_TABLE_SIZE * sizeof(UINT8));
+  InitLZWCode(source);
+
+  /*
+   * If image is interlaced, we read it into a full-size sample array,
+   * decompressing as we go; then get_interlaced_row selects rows from the
+   * sample array in the proper order.
+   */
+  if (source->is_interlaced) {
+    /* We request the virtual array now, but can't access it until virtual
+     * arrays have been allocated.  Hence, the actual work of reading the
+     * image is postponed until the first call to get_pixel_rows.
+     */
+    source->interlaced_image = (*cinfo->mem->request_virt_sarray)
+      ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
+       (JDIMENSION)width, (JDIMENSION)height, (JDIMENSION)1);
+    if (cinfo->progress != NULL) {
+      cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
+      progress->total_extra_passes++; /* count file input as separate pass */
+    }
+    source->pub.get_pixel_rows = load_interlaced_image;
+  } else {
+    source->pub.get_pixel_rows = get_pixel_rows;
+  }
+
+  /* Create compressor input buffer. */
+  source->pub.buffer = (*cinfo->mem->alloc_sarray)
+    ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)width * NUMCOLORS,
+     (JDIMENSION)1);
+  source->pub.buffer_height = 1;
+
+  /* Pad colormap for safety. */
+  for (c = colormaplen; c < source->clear_code; c++) {
+    source->colormap[CM_RED][c]   =
+    source->colormap[CM_GREEN][c] =
+    source->colormap[CM_BLUE][c]  = CENTERJSAMPLE;
+  }
+
+  /* Return info about the image. */
+  cinfo->in_color_space = JCS_RGB;
+  cinfo->input_components = NUMCOLORS;
+  cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
+  cinfo->image_width = width;
+  cinfo->image_height = height;
+
+  TRACEMS3(cinfo, 1, JTRC_GIF, width, height, colormaplen);
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for noninterlaced GIF images:
+ * we read directly from the GIF file.
+ */
+
+METHODDEF(JDIMENSION)
+get_pixel_rows(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+{
+  gif_source_ptr source = (gif_source_ptr)sinfo;
+  register int c;
+  register JSAMPROW ptr;
+  register JDIMENSION col;
+  register JSAMPARRAY colormap = source->colormap;
+
+  ptr = source->pub.buffer[0];
+  for (col = cinfo->image_width; col > 0; col--) {
+    c = LZWReadByte(source);
+    *ptr++ = colormap[CM_RED][c];
+    *ptr++ = colormap[CM_GREEN][c];
+    *ptr++ = colormap[CM_BLUE][c];
+  }
+  return 1;
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for the first call on get_pixel_rows when
+ * reading an interlaced GIF file: we read the whole image into memory.
+ */
+
+METHODDEF(JDIMENSION)
+load_interlaced_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+{
+  gif_source_ptr source = (gif_source_ptr)sinfo;
+  register JSAMPROW sptr;
+  register JDIMENSION col;
+  JDIMENSION row;
+  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
+
+  /* Read the interlaced image into the virtual array we've created. */
+  for (row = 0; row < cinfo->image_height; row++) {
+    if (progress != NULL) {
+      progress->pub.pass_counter = (long)row;
+      progress->pub.pass_limit = (long)cinfo->image_height;
+      (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
+    }
+    sptr = *(*cinfo->mem->access_virt_sarray)
+      ((j_common_ptr)cinfo, source->interlaced_image, row, (JDIMENSION)1,
+       TRUE);
+    for (col = cinfo->image_width; col > 0; col--) {
+      *sptr++ = (JSAMPLE)LZWReadByte(source);
+    }
+  }
+  if (progress != NULL)
+    progress->completed_extra_passes++;
+
+  /* Replace method pointer so subsequent calls don't come here. */
+  source->pub.get_pixel_rows = get_interlaced_row;
+  /* Initialize for get_interlaced_row, and perform first call on it. */
+  source->cur_row_number = 0;
+  source->pass2_offset = (cinfo->image_height + 7) / 8;
+  source->pass3_offset = source->pass2_offset + (cinfo->image_height + 3) / 8;
+  source->pass4_offset = source->pass3_offset + (cinfo->image_height + 1) / 4;
+
+  return get_interlaced_row(cinfo, sinfo);
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for interlaced GIF images:
+ * we read from the virtual array.
+ */
+
+METHODDEF(JDIMENSION)
+get_interlaced_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+{
+  gif_source_ptr source = (gif_source_ptr)sinfo;
+  register int c;
+  register JSAMPROW sptr, ptr;
+  register JDIMENSION col;
+  register JSAMPARRAY colormap = source->colormap;
+  JDIMENSION irow;
+
+  /* Figure out which row of interlaced image is needed, and access it. */
+  switch ((int)(source->cur_row_number & 7)) {
+  case 0:                       /* first-pass row */
+    irow = source->cur_row_number >> 3;
+    break;
+  case 4:                       /* second-pass row */
+    irow = (source->cur_row_number >> 3) + source->pass2_offset;
+    break;
+  case 2:                       /* third-pass row */
+  case 6:
+    irow = (source->cur_row_number >> 2) + source->pass3_offset;
+    break;
+  default:                      /* fourth-pass row */
+    irow = (source->cur_row_number >> 1) + source->pass4_offset;
+  }
+  sptr = *(*cinfo->mem->access_virt_sarray)
+    ((j_common_ptr)cinfo, source->interlaced_image, irow, (JDIMENSION)1,
+     FALSE);
+  /* Scan the row, expand colormap, and output */
+  ptr = source->pub.buffer[0];
+  for (col = cinfo->image_width; col > 0; col--) {
+    c = *sptr++;
+    *ptr++ = colormap[CM_RED][c];
+    *ptr++ = colormap[CM_GREEN][c];
+    *ptr++ = colormap[CM_BLUE][c];
+  }
+  source->cur_row_number++;     /* for next time */
+  return 1;
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF(void)
+finish_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+{
+  /* no work */
+}
+
+
 /*
  * The module selection routine for GIF format input.
  */
@@ -31,9 +675,21 @@
 GLOBAL(cjpeg_source_ptr)
 jinit_read_gif(j_compress_ptr cinfo)
 {
-  fprintf(stderr, "GIF input is unsupported for legal reasons.  Sorry.\n");
-  exit(EXIT_FAILURE);
-  return NULL;                  /* keep compiler happy */
+  gif_source_ptr source;
+
+  /* Create module interface object */
+  source = (gif_source_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                sizeof(gif_source_struct));
+  source->cinfo = cinfo;        /* make back link for subroutines */
+  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
+  source->pub.start_input = start_input_gif;
+  source->pub.finish_input = finish_input_gif;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  source->pub.max_pixels = 0;
+#endif
+
+  return (cjpeg_source_ptr)source;
 }
 
 #endif /* GIF_SUPPORTED */
diff --git a/src/third_party/libjpeg-turbo/rdjpgcom.c b/src/third_party/libjpeg-turbo/rdjpgcom.c
index e9f31d2..620270e 100644
--- a/src/third_party/libjpeg-turbo/rdjpgcom.c
+++ b/src/third_party/libjpeg-turbo/rdjpgcom.c
@@ -118,7 +118,6 @@
 #define M_SOI    0xD8           /* Start Of Image (beginning of datastream) */
 #define M_EOI    0xD9           /* End Of Image (end of datastream) */
 #define M_SOS    0xDA           /* Start Of Scan (begins compressed data) */
-#define M_APP0   0xE0           /* Application-specific marker, type N */
 #define M_APP12  0xEC           /* (we don't bother to list all 16 APPn's) */
 #define M_COM    0xFE           /* COMment */
 
diff --git a/src/third_party/libjpeg-turbo/rdppm.c b/src/third_party/libjpeg-turbo/rdppm.c
index f3bb79e..9699ca5 100644
--- a/src/third_party/libjpeg-turbo/rdppm.c
+++ b/src/third_party/libjpeg-turbo/rdppm.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1997, Thomas G. Lane.
  * Modified 2009 by Bill Allombert, Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2015-2017, D. R. Commander.
+ * Copyright (C) 2015-2017, 2020-2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -43,18 +43,8 @@
 
 /* Macros to deal with unsigned chars as efficiently as compiler allows */
 
-#ifdef HAVE_UNSIGNED_CHAR
 typedef unsigned char U_CHAR;
 #define UCH(x)  ((int)(x))
-#else /* !HAVE_UNSIGNED_CHAR */
-#ifdef __CHAR_UNSIGNED__
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x))
-#else
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x) & 0xFF)
-#endif
-#endif /* HAVE_UNSIGNED_CHAR */
 
 
 #define ReadOK(file, buffer, len) \
@@ -75,7 +65,7 @@
   JSAMPROW pixrow;              /* compressor input buffer */
   size_t buffer_width;          /* width of I/O buffer */
   JSAMPLE *rescale;             /* => maxval-remapping array, or NULL */
-  int maxval;
+  unsigned int maxval;
 } ppm_source_struct;
 
 typedef ppm_source_struct *ppm_source_ptr;
@@ -122,11 +112,10 @@
   while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
     val *= 10;
     val += ch - '0';
+    if (val > maxval)
+      ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
   }
 
-  if (val > maxval)
-    ERREXIT(cinfo, JERR_PPM_TOOLARGE);
-
   return val;
 }
 
@@ -509,7 +498,7 @@
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
     if (temp > maxval)
-      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
+      ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
     *ptr++ = rescale[temp];
   }
   return 1;
@@ -526,6 +515,11 @@
   register JSAMPLE *rescale = source->rescale;
   JDIMENSION col;
   unsigned int maxval = source->maxval;
+  register int rindex = rgb_red[cinfo->in_color_space];
+  register int gindex = rgb_green[cinfo->in_color_space];
+  register int bindex = rgb_blue[cinfo->in_color_space];
+  register int aindex = alpha_index[cinfo->in_color_space];
+  register int ps = rgb_pixelsize[cinfo->in_color_space];
 
   if (!ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
     ERREXIT(cinfo, JERR_INPUT_EOF);
@@ -536,18 +530,21 @@
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
     if (temp > maxval)
-      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
-    *ptr++ = rescale[temp];
+      ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+    ptr[rindex] = rescale[temp];
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
     if (temp > maxval)
-      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
-    *ptr++ = rescale[temp];
+      ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+    ptr[gindex] = rescale[temp];
     temp  = UCH(*bufferptr++) << 8;
     temp |= UCH(*bufferptr++);
     if (temp > maxval)
-      ERREXIT(cinfo, JERR_PPM_TOOLARGE);
-    *ptr++ = rescale[temp];
+      ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+    ptr[bindex] = rescale[temp];
+    if (aindex >= 0)
+      ptr[aindex] = 0xFF;
+    ptr += ps;
   }
   return 1;
 }
@@ -589,6 +586,10 @@
 
   if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
     ERREXIT(cinfo, JERR_PPM_NOT);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  if (sinfo->max_pixels && (unsigned long long)w * h > sinfo->max_pixels)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+#endif
 
   cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
   cinfo->image_width = (JDIMENSION)w;
@@ -634,7 +635,10 @@
       cinfo->in_color_space = JCS_GRAYSCALE;
     TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
     if (maxval > 255) {
-      source->pub.get_pixel_rows = get_word_gray_row;
+      if (cinfo->in_color_space == JCS_GRAYSCALE)
+        source->pub.get_pixel_rows = get_word_gray_row;
+      else
+        ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR) &&
                cinfo->in_color_space == JCS_GRAYSCALE) {
       source->pub.get_pixel_rows = get_raw_row;
@@ -657,13 +661,17 @@
       cinfo->in_color_space = JCS_EXT_RGB;
     TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
     if (maxval > 255) {
-      source->pub.get_pixel_rows = get_word_rgb_row;
+      if (IsExtRGB(cinfo->in_color_space))
+        source->pub.get_pixel_rows = get_word_rgb_row;
+      else
+        ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
     } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR) &&
-               (cinfo->in_color_space == JCS_EXT_RGB
 #if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
-                || cinfo->in_color_space == JCS_RGB
+               (cinfo->in_color_space == JCS_EXT_RGB ||
+                cinfo->in_color_space == JCS_RGB)) {
+#else
+               cinfo->in_color_space == JCS_EXT_RGB) {
 #endif
-               )) {
       source->pub.get_pixel_rows = get_raw_row;
       use_raw_buffer = TRUE;
       need_rescale = FALSE;
@@ -720,8 +728,10 @@
     /* On 16-bit-int machines we have to be careful of maxval = 65535 */
     source->rescale = (JSAMPLE *)
       (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                  (size_t)(((long)maxval + 1L) *
+                                  (size_t)(((long)MAX(maxval, 255) + 1L) *
                                            sizeof(JSAMPLE)));
+    MEMZERO(source->rescale, (size_t)(((long)MAX(maxval, 255) + 1L) *
+                                      sizeof(JSAMPLE)));
     half_maxval = maxval / 2;
     for (val = 0; val <= (long)maxval; val++) {
       /* The multiplication here must be done in 32 bits to avoid overflow */
@@ -759,6 +769,9 @@
   /* Fill in method ptrs, except get_pixel_rows which start_input sets */
   source->pub.start_input = start_input_ppm;
   source->pub.finish_input = finish_input_ppm;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  source->pub.max_pixels = 0;
+#endif
 
   return (cjpeg_source_ptr)source;
 }
diff --git a/src/third_party/libjpeg-turbo/rdrle.c b/src/third_party/libjpeg-turbo/rdrle.c
deleted file mode 100644
index b694514..0000000
--- a/src/third_party/libjpeg-turbo/rdrle.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * rdrle.c
- *
- * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1991-1996, Thomas G. Lane.
- * It was modified by The libjpeg-turbo Project to include only code and
- * information relevant to libjpeg-turbo.
- * For conditions of distribution and use, see the accompanying README.ijg
- * file.
- *
- * This file contains routines to read input images in Utah RLE format.
- * The Utah Raster Toolkit library is required (version 3.1 or later).
- *
- * These routines may need modification for non-Unix environments or
- * specialized applications.  As they stand, they assume input from
- * an ordinary stdio stream.  They further assume that reading begins
- * at the start of the file; start_input may need work if the
- * user interface has already read some data (e.g., to determine that
- * the file is indeed RLE format).
- *
- * Based on code contributed by Mike Lijewski,
- * with updates from Robert Hutchinson.
- */
-
-#include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
-
-#ifdef RLE_SUPPORTED
-
-/* rle.h is provided by the Utah Raster Toolkit. */
-
-#include <rle.h>
-
-/*
- * We assume that JSAMPLE has the same representation as rle_pixel,
- * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
- */
-
-#if BITS_IN_JSAMPLE != 8
-  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
-#endif
-
-/*
- * We support the following types of RLE files:
- *
- *   GRAYSCALE   - 8 bits, no colormap
- *   MAPPEDGRAY  - 8 bits, 1 channel colomap
- *   PSEUDOCOLOR - 8 bits, 3 channel colormap
- *   TRUECOLOR   - 24 bits, 3 channel colormap
- *   DIRECTCOLOR - 24 bits, no colormap
- *
- * For now, we ignore any alpha channel in the image.
- */
-
-typedef enum
-  { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
-
-
-/*
- * Since RLE stores scanlines bottom-to-top, we have to invert the image
- * to conform to JPEG's top-to-bottom order.  To do this, we read the
- * incoming image into a virtual array on the first get_pixel_rows call,
- * then fetch the required row from the virtual array on subsequent calls.
- */
-
-typedef struct _rle_source_struct *rle_source_ptr;
-
-typedef struct _rle_source_struct {
-  struct cjpeg_source_struct pub; /* public fields */
-
-  rle_kind visual;              /* actual type of input file */
-  jvirt_sarray_ptr image;       /* virtual array to hold the image */
-  JDIMENSION row;               /* current row # in the virtual array */
-  rle_hdr header;               /* Input file information */
-  rle_pixel **rle_row;          /* holds a row returned by rle_getrow() */
-
-} rle_source_struct;
-
-
-/*
- * Read the file header; return image size and component count.
- */
-
-METHODDEF(void)
-start_input_rle(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  rle_source_ptr source = (rle_source_ptr)sinfo;
-  JDIMENSION width, height;
-#ifdef PROGRESS_REPORT
-  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
-#endif
-
-  /* Use RLE library routine to get the header info */
-  source->header = *rle_hdr_init(NULL);
-  source->header.rle_file = source->pub.input_file;
-  switch (rle_get_setup(&(source->header))) {
-  case RLE_SUCCESS:
-    /* A-OK */
-    break;
-  case RLE_NOT_RLE:
-    ERREXIT(cinfo, JERR_RLE_NOT);
-    break;
-  case RLE_NO_SPACE:
-    ERREXIT(cinfo, JERR_RLE_MEM);
-    break;
-  case RLE_EMPTY:
-    ERREXIT(cinfo, JERR_RLE_EMPTY);
-    break;
-  case RLE_EOF:
-    ERREXIT(cinfo, JERR_RLE_EOF);
-    break;
-  default:
-    ERREXIT(cinfo, JERR_RLE_BADERROR);
-    break;
-  }
-
-  /* Figure out what we have, set private vars and return values accordingly */
-
-  width  = source->header.xmax - source->header.xmin + 1;
-  height = source->header.ymax - source->header.ymin + 1;
-  source->header.xmin = 0;              /* realign horizontally */
-  source->header.xmax = width - 1;
-
-  cinfo->image_width      = width;
-  cinfo->image_height     = height;
-  cinfo->data_precision   = 8;  /* we can only handle 8 bit data */
-
-  if (source->header.ncolors == 1 && source->header.ncmap == 0) {
-    source->visual     = GRAYSCALE;
-    TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height);
-  } else if (source->header.ncolors == 1 && source->header.ncmap == 1) {
-    source->visual     = MAPPEDGRAY;
-    TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height,
-             1 << source->header.cmaplen);
-  } else if (source->header.ncolors == 1 && source->header.ncmap == 3) {
-    source->visual     = PSEUDOCOLOR;
-    TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height,
-             1 << source->header.cmaplen);
-  } else if (source->header.ncolors == 3 && source->header.ncmap == 3) {
-    source->visual     = TRUECOLOR;
-    TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height,
-             1 << source->header.cmaplen);
-  } else if (source->header.ncolors == 3 && source->header.ncmap == 0) {
-    source->visual     = DIRECTCOLOR;
-    TRACEMS2(cinfo, 1, JTRC_RLE, width, height);
-  } else
-    ERREXIT(cinfo, JERR_RLE_UNSUPPORTED);
-
-  if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) {
-    cinfo->in_color_space   = JCS_GRAYSCALE;
-    cinfo->input_components = 1;
-  } else {
-    cinfo->in_color_space   = JCS_RGB;
-    cinfo->input_components = 3;
-  }
-
-  /*
-   * A place to hold each scanline while it's converted.
-   * (GRAYSCALE scanlines don't need converting)
-   */
-  if (source->visual != GRAYSCALE) {
-    source->rle_row = (rle_pixel **)(*cinfo->mem->alloc_sarray)
-      ((j_common_ptr)cinfo, JPOOL_IMAGE,
-       (JDIMENSION)width, (JDIMENSION)cinfo->input_components);
-  }
-
-  /* request a virtual array to hold the image */
-  source->image = (*cinfo->mem->request_virt_sarray)
-    ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
-     (JDIMENSION)(width * source->header.ncolors),
-     (JDIMENSION)height, (JDIMENSION)1);
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL) {
-    /* count file input as separate pass */
-    progress->total_extra_passes++;
-  }
-#endif
-
-  source->pub.buffer_height = 1;
-}
-
-
-/*
- * Read one row of pixels.
- * Called only after load_image has read the image into the virtual array.
- * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images.
- */
-
-METHODDEF(JDIMENSION)
-get_rle_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  rle_source_ptr source = (rle_source_ptr)sinfo;
-
-  source->row--;
-  source->pub.buffer = (*cinfo->mem->access_virt_sarray)
-    ((j_common_ptr)cinfo, source->image, source->row, (JDIMENSION)1, FALSE);
-
-  return 1;
-}
-
-/*
- * Read one row of pixels.
- * Called only after load_image has read the image into the virtual array.
- * Used for PSEUDOCOLOR images.
- */
-
-METHODDEF(JDIMENSION)
-get_pseudocolor_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  rle_source_ptr source = (rle_source_ptr)sinfo;
-  JSAMPROW src_row, dest_row;
-  JDIMENSION col;
-  rle_map *colormap;
-  int val;
-
-  colormap = source->header.cmap;
-  dest_row = source->pub.buffer[0];
-  source->row--;
-  src_row = *(*cinfo->mem->access_virt_sarray)
-    ((j_common_ptr)cinfo, source->image, source->row, (JDIMENSION)1, FALSE);
-
-  for (col = cinfo->image_width; col > 0; col--) {
-    val = GETJSAMPLE(*src_row++);
-    *dest_row++ = (JSAMPLE)(colormap[val      ] >> 8);
-    *dest_row++ = (JSAMPLE)(colormap[val + 256] >> 8);
-    *dest_row++ = (JSAMPLE)(colormap[val + 512] >> 8);
-  }
-
-  return 1;
-}
-
-
-/*
- * Load the image into a virtual array.  We have to do this because RLE
- * files start at the lower left while the JPEG standard has them starting
- * in the upper left.  This is called the first time we want to get a row
- * of input.  What we do is load the RLE data into the array and then call
- * the appropriate routine to read one row from the array.  Before returning,
- * we set source->pub.get_pixel_rows so that subsequent calls go straight to
- * the appropriate row-reading routine.
- */
-
-METHODDEF(JDIMENSION)
-load_image(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  rle_source_ptr source = (rle_source_ptr)sinfo;
-  JDIMENSION row, col;
-  JSAMPROW scanline, red_ptr, green_ptr, blue_ptr;
-  rle_pixel **rle_row;
-  rle_map *colormap;
-  char channel;
-#ifdef PROGRESS_REPORT
-  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
-#endif
-
-  colormap = source->header.cmap;
-  rle_row = source->rle_row;
-
-  /* Read the RLE data into our virtual array.
-   * We assume here that rle_pixel is represented the same as JSAMPLE.
-   */
-  RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL) {
-    progress->pub.pass_limit = cinfo->image_height;
-    progress->pub.pass_counter = 0;
-    (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-  }
-#endif
-
-  switch (source->visual) {
-
-  case GRAYSCALE:
-  case PSEUDOCOLOR:
-    for (row = 0; row < cinfo->image_height; row++) {
-      rle_row = (rle_pixel **)(*cinfo->mem->access_virt_sarray)
-        ((j_common_ptr)cinfo, source->image, row, (JDIMENSION)1, TRUE);
-      rle_getrow(&source->header, rle_row);
-#ifdef PROGRESS_REPORT
-      if (progress != NULL) {
-        progress->pub.pass_counter++;
-        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-      }
-#endif
-    }
-    break;
-
-  case MAPPEDGRAY:
-  case TRUECOLOR:
-    for (row = 0; row < cinfo->image_height; row++) {
-      scanline = *(*cinfo->mem->access_virt_sarray)
-        ((j_common_ptr)cinfo, source->image, row, (JDIMENSION)1, TRUE);
-      rle_row = source->rle_row;
-      rle_getrow(&source->header, rle_row);
-
-      for (col = 0; col < cinfo->image_width; col++) {
-        for (channel = 0; channel < source->header.ncolors; channel++) {
-          *scanline++ = (JSAMPLE)
-            (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
-        }
-      }
-
-#ifdef PROGRESS_REPORT
-      if (progress != NULL) {
-        progress->pub.pass_counter++;
-        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-      }
-#endif
-    }
-    break;
-
-  case DIRECTCOLOR:
-    for (row = 0; row < cinfo->image_height; row++) {
-      scanline = *(*cinfo->mem->access_virt_sarray)
-        ((j_common_ptr)cinfo, source->image, row, (JDIMENSION)1, TRUE);
-      rle_getrow(&source->header, rle_row);
-
-      red_ptr   = rle_row[0];
-      green_ptr = rle_row[1];
-      blue_ptr  = rle_row[2];
-
-      for (col = cinfo->image_width; col > 0; col--) {
-        *scanline++ = *red_ptr++;
-        *scanline++ = *green_ptr++;
-        *scanline++ = *blue_ptr++;
-      }
-
-#ifdef PROGRESS_REPORT
-      if (progress != NULL) {
-        progress->pub.pass_counter++;
-        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-      }
-#endif
-    }
-  }
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL)
-    progress->completed_extra_passes++;
-#endif
-
-  /* Set up to call proper row-extraction routine in future */
-  if (source->visual == PSEUDOCOLOR) {
-    source->pub.buffer = source->rle_row;
-    source->pub.get_pixel_rows = get_pseudocolor_row;
-  } else {
-    source->pub.get_pixel_rows = get_rle_row;
-  }
-  source->row = cinfo->image_height;
-
-  /* And fetch the topmost (bottommost) row */
-  return (*source->pub.get_pixel_rows) (cinfo, sinfo);
-}
-
-
-/*
- * Finish up at the end of the file.
- */
-
-METHODDEF(void)
-finish_input_rle(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  /* no work */
-}
-
-
-/*
- * The module selection routine for RLE format input.
- */
-
-GLOBAL(cjpeg_source_ptr)
-jinit_read_rle(j_compress_ptr cinfo)
-{
-  rle_source_ptr source;
-
-  /* Create module interface object */
-  source = (rle_source_ptr)
-    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                sizeof(rle_source_struct));
-  /* Fill in method ptrs */
-  source->pub.start_input = start_input_rle;
-  source->pub.finish_input = finish_input_rle;
-  source->pub.get_pixel_rows = load_image;
-
-  return (cjpeg_source_ptr)source;
-}
-
-#endif /* RLE_SUPPORTED */
diff --git a/src/third_party/libjpeg-turbo/rdswitch.c b/src/third_party/libjpeg-turbo/rdswitch.c
index 610346b..886fec3 100644
--- a/src/third_party/libjpeg-turbo/rdswitch.c
+++ b/src/third_party/libjpeg-turbo/rdswitch.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2010, D. R. Commander.
+ * Copyright (C) 2010, 2018, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -276,7 +276,8 @@
 
 
 #if JPEG_LIB_VERSION < 70
-/* These are the sample quantization tables given in JPEG spec section K.1.
+/* These are the sample quantization tables given in Annex K (Clause K.1) of
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
  * The spec says that the values given produce "good" quality, and
  * when divided by 2, "very good" quality.
  */
@@ -337,8 +338,8 @@
 #else
       q_scale_factor[tblno] = jpeg_quality_scaling(val);
 #endif
-      while (*arg && *arg++ != ',') /* advance to next segment of arg string */
-        ;
+      while (*arg && *arg++ != ','); /* advance to next segment of arg
+                                        string */
     } else {
       /* reached end of parameter, set remaining factors to last value */
 #if JPEG_LIB_VERSION >= 70
@@ -377,8 +378,8 @@
         return FALSE;
       }
       cinfo->comp_info[ci].quant_tbl_no = val;
-      while (*arg && *arg++ != ',') /* advance to next segment of arg string */
-        ;
+      while (*arg && *arg++ != ','); /* advance to next segment of arg
+                                        string */
     } else {
       /* reached end of parameter, set remaining components to last table */
       cinfo->comp_info[ci].quant_tbl_no = val;
@@ -411,8 +412,8 @@
       }
       cinfo->comp_info[ci].h_samp_factor = val1;
       cinfo->comp_info[ci].v_samp_factor = val2;
-      while (*arg && *arg++ != ',') /* advance to next segment of arg string */
-        ;
+      while (*arg && *arg++ != ',');  /* advance to next segment of arg
+                                         string */
     } else {
       /* reached end of parameter, set remaining components to 1x1 sampling */
       cinfo->comp_info[ci].h_samp_factor = 1;
diff --git a/src/third_party/libjpeg-turbo/rdtarga.c b/src/third_party/libjpeg-turbo/rdtarga.c
index ecb4219..8f2d031 100644
--- a/src/third_party/libjpeg-turbo/rdtarga.c
+++ b/src/third_party/libjpeg-turbo/rdtarga.c
@@ -3,8 +3,9 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1996, Thomas G. Lane.
- * It was modified by The libjpeg-turbo Project to include only code relevant
- * to libjpeg-turbo.
+ * Modified 2017 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2018, 2021, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -27,18 +28,8 @@
 
 /* Macros to deal with unsigned chars as efficiently as compiler allows */
 
-#ifdef HAVE_UNSIGNED_CHAR
 typedef unsigned char U_CHAR;
 #define UCH(x)  ((int)(x))
-#else /* !HAVE_UNSIGNED_CHAR */
-#ifdef __CHAR_UNSIGNED__
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x))
-#else
-typedef char U_CHAR;
-#define UCH(x)  ((int)(x) & 0xFF)
-#endif
-#endif /* HAVE_UNSIGNED_CHAR */
 
 
 #define ReadOK(file, buffer, len) \
@@ -66,6 +57,7 @@
   U_CHAR tga_pixel[4];
 
   int pixel_size;               /* Bytes per Targa pixel (1 to 4) */
+  int cmap_length;              /* colormap length */
 
   /* State info for reading RLE-coded pixels; both counts must be init to 0 */
   int block_count;              /* # of pixels remaining in RLE block */
@@ -126,11 +118,10 @@
 read_non_rle_pixel(tga_source_ptr sinfo)
 /* Read one Targa pixel from the input file; no RLE expansion */
 {
-  register FILE *infile = sinfo->pub.input_file;
   register int i;
 
   for (i = 0; i < sinfo->pixel_size; i++) {
-    sinfo->tga_pixel[i] = (U_CHAR)getc(infile);
+    sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo);
   }
 }
 
@@ -139,7 +130,6 @@
 read_rle_pixel(tga_source_ptr sinfo)
 /* Read one Targa pixel from the input file, expanding RLE data as needed */
 {
-  register FILE *infile = sinfo->pub.input_file;
   register int i;
 
   /* Duplicate previously read pixel? */
@@ -161,7 +151,7 @@
 
   /* Read next pixel */
   for (i = 0; i < sinfo->pixel_size; i++) {
-    sinfo->tga_pixel[i] = (U_CHAR)getc(infile);
+    sinfo->tga_pixel[i] = (U_CHAR)read_byte(sinfo);
   }
 }
 
@@ -198,11 +188,14 @@
   register JSAMPROW ptr;
   register JDIMENSION col;
   register JSAMPARRAY colormap = source->colormap;
+  int cmaplen = source->cmap_length;
 
   ptr = source->pub.buffer[0];
   for (col = cinfo->image_width; col > 0; col--) {
     (*source->read_pixel) (source); /* Load next pixel into tga_pixel */
     t = UCH(source->tga_pixel[0]);
+    if (t >= cmaplen)
+      ERREXIT(cinfo, JERR_TGA_BADPARMS);
     *ptr++ = colormap[0][t];
     *ptr++ = colormap[1][t];
     *ptr++ = colormap[2][t];
@@ -341,8 +334,9 @@
   unsigned int width, height, maplen;
   boolean is_bottom_up;
 
-#define GET_2B(offset)  ((unsigned int)UCH(targaheader[offset]) + \
-                         (((unsigned int)UCH(targaheader[offset + 1])) << 8))
+#define GET_2B(offset) \
+  ((unsigned int)UCH(targaheader[offset]) + \
+   (((unsigned int)UCH(targaheader[offset + 1])) << 8))
 
   if (!ReadOK(source->pub.input_file, targaheader, 18))
     ERREXIT(cinfo, JERR_INPUT_EOF);
@@ -369,6 +363,11 @@
       interlace_type != 0 ||      /* currently don't allow interlaced image */
       width == 0 || height == 0)  /* image width/height must be non-zero */
     ERREXIT(cinfo, JERR_TGA_BADPARMS);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  if (sinfo->max_pixels &&
+      (unsigned long long)width * height > sinfo->max_pixels)
+    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+#endif
 
   if (subtype > 8) {
     /* It's an RLE-coded file */
@@ -454,12 +453,14 @@
     /* Allocate space to store the colormap */
     source->colormap = (*cinfo->mem->alloc_sarray)
       ((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)maplen, (JDIMENSION)3);
+    source->cmap_length = (int)maplen;
     /* and read it from the file */
     read_colormap(source, (int)maplen, UCH(targaheader[7]));
   } else {
     if (cmaptype)               /* but you promised a cmap! */
       ERREXIT(cinfo, JERR_TGA_BADPARMS);
     source->colormap = NULL;
+    source->cmap_length = 0;
   }
 
   cinfo->input_components = components;
@@ -497,6 +498,9 @@
   /* Fill in method ptrs, except get_pixel_rows which start_input sets */
   source->pub.start_input = start_input_tga;
   source->pub.finish_input = finish_input_tga;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  source->pub.max_pixels = 0;
+#endif
 
   return (cjpeg_source_ptr)source;
 }
diff --git a/src/third_party/libjpeg-turbo/release/Distribution.xml.in b/src/third_party/libjpeg-turbo/release/Distribution.xml.in
deleted file mode 100644
index e1f79ee..0000000
--- a/src/third_party/libjpeg-turbo/release/Distribution.xml.in
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<installer-gui-script minSpecVersion="1">
-	<title>@CMAKE_PROJECT_NAME@</title>
-	<welcome file="Welcome.rtf" />
-	<readme file="ReadMe.txt" />
-	<license file="License.rtf" />
-	<domains
-		enable_anywhere="false"
-		enable_currentUserHome="false"
-		enable_localSystem="true"
-	/>
-	<options customize="never" />
-	<choices-outline>
-		<line choice="default">
-			<line choice="@PKGID@"/>
-		</line>
-	</choices-outline>
-	<choice id="default"/>
-	<choice id="@PKGID@" visible="false">
-		<pkg-ref id="@PKGID@"/>
-	</choice>
-	<pkg-ref auth="root"
-		id="@PKGID@">@PKGNAME@.pkg</pkg-ref>
-</installer-gui-script>
diff --git a/src/third_party/libjpeg-turbo/release/License.rtf b/src/third_party/libjpeg-turbo/release/License.rtf
deleted file mode 100755
index 5073a27..0000000
--- a/src/third_party/libjpeg-turbo/release/License.rtf
+++ /dev/null
@@ -1,20 +0,0 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
-{\colortbl;\red255\green255\blue255;}
-{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
-{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
-\margl1440\margr1440\vieww9820\viewh8480\viewkind0
-\deftab720
-\pard\pardeftab720
-
-\f0\fs24 \cf0 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\
-\
-\pard\tx220\tx720\pardeftab720\li720\fi-720
-\ls1\ilvl0\cf0 {\listtext	\'95	}Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\
-{\listtext	\'95	}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.\
-{\listtext	\'95	}Neither the name of the libjpeg-turbo Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\
-\pard\pardeftab720\qc
-\cf0 \
-\pard\pardeftab720
-\cf0 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 HOLDERS 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.\
-}
\ No newline at end of file
diff --git a/src/third_party/libjpeg-turbo/release/ReadMe.txt b/src/third_party/libjpeg-turbo/release/ReadMe.txt
deleted file mode 100644
index cf9012a..0000000
--- a/src/third_party/libjpeg-turbo/release/ReadMe.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2, AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG compression on x86 and x86-64 systems.  On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg, all else being equal.  On other types of systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by virtue of its highly-optimized Huffman coding routines.  In many cases, the performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
-
-libjpeg-turbo implements both the traditional libjpeg API as well as the less powerful but more straightforward TurboJPEG API.  libjpeg-turbo also features colorspace extensions that allow it to compress from/decompress to 32-bit and big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java interface.
-
-libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated derivative of libjpeg v6b developed by Miyasaka Masaru.  The TigerVNC and VirtualGL projects made numerous enhancements to the codec in 2009, and in early 2010, libjpeg-turbo spun off into an independent project, with the goal of making high-speed JPEG compression/decompression technology available to a broader range of users and developers.
diff --git a/src/third_party/libjpeg-turbo/release/Welcome.rtf b/src/third_party/libjpeg-turbo/release/Welcome.rtf
deleted file mode 100755
index a570c5b..0000000
--- a/src/third_party/libjpeg-turbo/release/Welcome.rtf
+++ /dev/null
@@ -1,17 +0,0 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPSMT;}
-{\colortbl;\red255\green255\blue255;}
-\margl1440\margr1440\vieww9000\viewh8400\viewkind0
-\deftab720
-\pard\pardeftab720\ql\qnatural
-
-\f0\fs24 \cf0 This installer will install the libjpeg-turbo SDK and run-time libraries onto your computer so that you can use libjpeg-turbo to build new applications or accelerate existing ones.  To remove the libjpeg-turbo package, run\
-\
-\pard\pardeftab720\ql\qnatural
-
-\f1 \cf0   /opt/libjpeg-turbo/bin/uninstall\
-\pard\pardeftab720\ql\qnatural
-
-\f0 \cf0 \
-from the command line.\
-}
\ No newline at end of file
diff --git a/src/third_party/libjpeg-turbo/release/deb-control.in b/src/third_party/libjpeg-turbo/release/deb-control.in
deleted file mode 100644
index 08131c6..0000000
--- a/src/third_party/libjpeg-turbo/release/deb-control.in
+++ /dev/null
@@ -1,32 +0,0 @@
-Package: {__PKGNAME}
-Version: @VERSION@-@BUILD@
-Section: misc
-Priority: optional
-Architecture: {__ARCH}
-Essential: no
-Maintainer: @PKGVENDOR@ <@PKGEMAIL@>
-Homepage: @PKGURL@
-Installed-Size: {__SIZE}
-Description: A SIMD-accelerated JPEG codec that provides both the libjpeg and TurboJPEG APIs
- libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
- AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
- on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
- compression on x86 and x86-64 systems.  On such systems, libjpeg-turbo is
- generally 2-6x as fast as libjpeg, all else being equal.  On other types of
- systems, libjpeg-turbo can still outperform libjpeg by a significant amount,
- by virtue of its highly-optimized Huffman coding routines.  In many cases, the
- performance of libjpeg-turbo rivals that of proprietary high-speed JPEG
- codecs.
- .
- libjpeg-turbo implements both the traditional libjpeg API as well as the less
- powerful but more straightforward TurboJPEG API.  libjpeg-turbo also features
- colorspace extensions that allow it to compress from/decompress to 32-bit and
- big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
- interface.
- .
- libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
- derivative of libjpeg v6b developed by Miyasaka Masaru.  The TigerVNC and
- VirtualGL projects made numerous enhancements to the codec in 2009, and in
- early 2010, libjpeg-turbo spun off into an independent project, with the goal
- of making high-speed JPEG compression/decompression technology available to a
- broader range of users and developers.
diff --git a/src/third_party/libjpeg-turbo/release/installer.nsi.in b/src/third_party/libjpeg-turbo/release/installer.nsi.in
deleted file mode 100755
index 00cd5f8..0000000
--- a/src/third_party/libjpeg-turbo/release/installer.nsi.in
+++ /dev/null
@@ -1,193 +0,0 @@
-!include x64.nsh
-Name "@CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@"
-OutFile "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}@INST_NAME@.exe"
-InstallDir "@INST_DIR@"
-
-SetCompressor bzip2
-
-Page directory
-Page instfiles
-
-UninstPage uninstConfirm
-UninstPage instfiles
-
-Section "@CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@ (required)"
-!ifdef WIN64
-	${If} ${RunningX64}
-	${DisableX64FSRedirection}
-	${Endif}
-!endif
-	SectionIn RO
-!ifdef GCC
-	IfFileExists $SYSDIR/libturbojpeg.dll exists 0
-!else
-	IfFileExists $SYSDIR/turbojpeg.dll exists 0
-!endif
-	goto notexists
-	exists:
-!ifdef GCC
-	MessageBox MB_OK "An existing version of the @CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@ is already installed.  Please uninstall it first."
-!else
-	MessageBox MB_OK "An existing version of the @CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@ or the TurboJPEG SDK is already installed.  Please uninstall it first."
-!endif
-	quit
-
-	notexists:
-	SetOutPath $SYSDIR
-!ifdef GCC
-	File "@CMAKE_CURRENT_BINARY_DIR@\libturbojpeg.dll"
-!else
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg.dll"
-!endif
-	SetOutPath $INSTDIR\bin
-!ifdef GCC
-	File "@CMAKE_CURRENT_BINARY_DIR@\libturbojpeg.dll"
-!else
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg.dll"
-!endif
-!ifdef GCC
-	File "@CMAKE_CURRENT_BINARY_DIR@\libjpeg-@SO_MAJOR_VERSION@.dll"
-!else
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpeg@SO_MAJOR_VERSION@.dll"
-!endif
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}cjpeg.exe"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}djpeg.exe"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpegtran.exe"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}tjbench.exe"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}rdjpgcom.exe"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}wrjpgcom.exe"
-	SetOutPath $INSTDIR\lib
-!ifdef GCC
-	File "@CMAKE_CURRENT_BINARY_DIR@\libturbojpeg.dll.a"
-	File "@CMAKE_CURRENT_BINARY_DIR@\libturbojpeg.a"
-	File "@CMAKE_CURRENT_BINARY_DIR@\libjpeg.dll.a"
-	File "@CMAKE_CURRENT_BINARY_DIR@\libjpeg.a"
-	SetOutPath $INSTDIR\lib\pkgconfig
-	File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libjpeg.pc"
-	File "@CMAKE_CURRENT_BINARY_DIR@\pkgscripts\libturbojpeg.pc"
-!else
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg.lib"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}turbojpeg-static.lib"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpeg.lib"
-	File "@CMAKE_CURRENT_BINARY_DIR@\${BUILDDIR}jpeg-static.lib"
-!endif
-!ifdef JAVA
-	SetOutPath $INSTDIR\classes
-	File "@CMAKE_CURRENT_BINARY_DIR@\java\turbojpeg.jar"
-!endif
-	SetOutPath $INSTDIR\include
-	File "@CMAKE_CURRENT_BINARY_DIR@\jconfig.h"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\jerror.h"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\jmorecfg.h"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\jpeglib.h"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\turbojpeg.h"
-	SetOutPath $INSTDIR\doc
-	File "@CMAKE_CURRENT_SOURCE_DIR@\README.ijg"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\README.md"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\LICENSE.md"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\example.txt"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\libjpeg.txt"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\structure.txt"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\usage.txt"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\wizard.txt"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\tjexample.c"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\java\TJExample.java"
-!ifdef GCC
-	SetOutPath $INSTDIR\man\man1
-	File "@CMAKE_CURRENT_SOURCE_DIR@\cjpeg.1"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\djpeg.1"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\jpegtran.1"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\rdjpgcom.1"
-	File "@CMAKE_CURRENT_SOURCE_DIR@\wrjpgcom.1"
-!endif
-
-	WriteRegStr HKLM "SOFTWARE\@INST_REG_NAME@ @VERSION@" "Install_Dir" "$INSTDIR"
-
-	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@INST_REG_NAME@ @VERSION@" "DisplayName" "@CMAKE_PROJECT_NAME@ SDK v@VERSION@ for @INST_PLATFORM@"
-	WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@INST_REG_NAME@ @VERSION@" "UninstallString" '"$INSTDIR\uninstall_@VERSION@.exe"'
-	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@INST_REG_NAME@ @VERSION@" "NoModify" 1
-	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@INST_REG_NAME@ @VERSION@" "NoRepair" 1
-	WriteUninstaller "uninstall_@VERSION@.exe"
-SectionEnd
-
-Section "Uninstall"
-!ifdef WIN64
-	${If} ${RunningX64}
-	${DisableX64FSRedirection}
-	${Endif}
-!endif
-
-	SetShellVarContext all
-
-	DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@INST_REG_NAME@ @VERSION@"
-	DeleteRegKey HKLM "SOFTWARE\@INST_REG_NAME@ @VERSION@"
-
-!ifdef GCC
-	Delete $INSTDIR\bin\libjpeg-@SO_MAJOR_VERSION@.dll
-	Delete $INSTDIR\bin\libturbojpeg.dll
-	Delete $SYSDIR\libturbojpeg.dll
-	Delete $INSTDIR\lib\libturbojpeg.dll.a
-	Delete $INSTDIR\lib\libturbojpeg.a
-	Delete $INSTDIR\lib\libjpeg.dll.a
-	Delete $INSTDIR\lib\libjpeg.a
-	Delete $INSTDIR\lib\pkgconfig\libjpeg.pc
-	Delete $INSTDIR\lib\pkgconfig\libturbojpeg.pc
-!else
-	Delete $INSTDIR\bin\jpeg@SO_MAJOR_VERSION@.dll
-	Delete $INSTDIR\bin\turbojpeg.dll
-	Delete $SYSDIR\turbojpeg.dll
-	Delete $INSTDIR\lib\jpeg.lib
-	Delete $INSTDIR\lib\jpeg-static.lib
-	Delete $INSTDIR\lib\turbojpeg.lib
-	Delete $INSTDIR\lib\turbojpeg-static.lib
-!endif
-!ifdef JAVA
-	Delete $INSTDIR\classes\turbojpeg.jar
-!endif
-	Delete $INSTDIR\bin\cjpeg.exe
-	Delete $INSTDIR\bin\djpeg.exe
-	Delete $INSTDIR\bin\jpegtran.exe
-	Delete $INSTDIR\bin\tjbench.exe
-	Delete $INSTDIR\bin\rdjpgcom.exe
-	Delete $INSTDIR\bin\wrjpgcom.exe
-	Delete $INSTDIR\include\jconfig.h
-	Delete $INSTDIR\include\jerror.h
-	Delete $INSTDIR\include\jmorecfg.h
-	Delete $INSTDIR\include\jpeglib.h
-	Delete $INSTDIR\include\turbojpeg.h
-	Delete $INSTDIR\uninstall_@VERSION@.exe
-	Delete $INSTDIR\doc\README.ijg
-	Delete $INSTDIR\doc\README.md
-	Delete $INSTDIR\doc\LICENSE.md
-	Delete $INSTDIR\doc\example.txt
-	Delete $INSTDIR\doc\libjpeg.txt
-	Delete $INSTDIR\doc\structure.txt
-	Delete $INSTDIR\doc\usage.txt
-	Delete $INSTDIR\doc\wizard.txt
-	Delete $INSTDIR\doc\tjexample.c
-	Delete $INSTDIR\doc\TJExample.java
-!ifdef GCC
-	Delete $INSTDIR\man\man1\cjpeg.1
-	Delete $INSTDIR\man\man1\djpeg.1
-	Delete $INSTDIR\man\man1\jpegtran.1
-	Delete $INSTDIR\man\man1\rdjpgcom.1
-	Delete $INSTDIR\man\man1\wrjpgcom.1
-!endif
-
-	RMDir "$INSTDIR\include"
-!ifdef GCC
-	RMDir "$INSTDIR\lib\pkgconfig"
-!endif
-	RMDir "$INSTDIR\lib"
-	RMDir "$INSTDIR\doc"
-!ifdef GCC
-	RMDir "$INSTDIR\man\man1"
-	RMDir "$INSTDIR\man"
-!endif
-!ifdef JAVA
-	RMDir "$INSTDIR\classes"
-!endif
-	RMDir "$INSTDIR\bin"
-	RMDir "$INSTDIR"
-
-SectionEnd
diff --git a/src/third_party/libjpeg-turbo/release/libjpeg.pc.in b/src/third_party/libjpeg-turbo/release/libjpeg.pc.in
deleted file mode 100644
index 74fb7fc..0000000
--- a/src/third_party/libjpeg-turbo/release/libjpeg.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=@CMAKE_INSTALL_PREFIX@
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: libjpeg
-Description: A SIMD-accelerated JPEG codec that provides the libjpeg API
-Version: @VERSION@
-Libs: -L${libdir} -ljpeg
-Cflags: -I${includedir}
diff --git a/src/third_party/libjpeg-turbo/release/libturbojpeg.pc.in b/src/third_party/libjpeg-turbo/release/libturbojpeg.pc.in
deleted file mode 100644
index 81a0063..0000000
--- a/src/third_party/libjpeg-turbo/release/libturbojpeg.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=@CMAKE_INSTALL_PREFIX@
-libdir=@CMAKE_INSTALL_FULL_LIBDIR@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: libturbojpeg
-Description: A SIMD-accelerated JPEG codec that provides the TurboJPEG API
-Version: @VERSION@
-Libs: -L${libdir} -lturbojpeg
-Cflags: -I${includedir}
diff --git a/src/third_party/libjpeg-turbo/release/makecygwinpkg.in b/src/third_party/libjpeg-turbo/release/makecygwinpkg.in
deleted file mode 100755
index b7f353e..0000000
--- a/src/third_party/libjpeg-turbo/release/makecygwinpkg.in
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		rm -rf $TMPDIR
-	fi
-}
-
-safedirmove ()
-{
-	if [ "$1" = "$2" ]; then
-		return 0
-	fi
-	if [ "$1" = "" -o ! -d "$1" ]; then
-		echo safedirmove: source dir $1 is not valid
-		return 1
-	fi
-	if [ "$2" = "" -o -e "$2" ]; then
-		echo safedirmove: dest dir $2 is not valid
-		return 1
-	fi
-	if [ "$3" = "" -o -e "$3" ]; then
-		echo safedirmove: tmp dir $3 is not valid
-		return 1
-	fi
-	mkdir -p $3
-	mv $1/* $3/
-	rmdir $1
-	mkdir -p $2
-	mv $3/* $2/
-	rmdir $3
-	return 0
-}
-
-PKGNAME=@PKGNAME@
-VERSION=@VERSION@
-BUILD=@BUILD@
-
-PREFIX=@CMAKE_INSTALL_PREFIX@
-DOCDIR=@CMAKE_INSTALL_FULL_DOCDIR@
-LIBDIR=@CMAKE_INSTALL_FULL_LIBDIR@
-
-umask 022
-rm -f $PKGNAME-$VERSION-$BUILD.tar.bz2
-TMPDIR=`mktemp -d /tmp/ljtbuild.XXXXXX`
-__PWD=`pwd`
-make install DESTDIR=$TMPDIR/pkg
-if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$DOCDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/doc" ]; then
-	safedirmove $TMPDIR/pkg$DOCDIR $TMPDIR/pkg/usr/share/doc/$PKGNAME-$VERSION $TMPDIR/__tmpdoc
-	ln -fs /usr/share/doc/$PKGNAME-$VERSION $TMPDIR/pkg$DOCDIR
-fi
-cd $TMPDIR/pkg
-tar cfj ../$PKGNAME-$VERSION-$BUILD.tar.bz2 *
-cd $__PWD
-mv $TMPDIR/*.tar.bz2 .
-
-exit 0
diff --git a/src/third_party/libjpeg-turbo/release/makedpkg.in b/src/third_party/libjpeg-turbo/release/makedpkg.in
deleted file mode 100644
index 77836dd..0000000
--- a/src/third_party/libjpeg-turbo/release/makedpkg.in
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-SUDO=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		$SUDO rm -rf $TMPDIR
-	fi
-}
-
-uid()
-{
-	id | cut -f2 -d = | cut -f1 -d \(;
-}
-
-safedirmove ()
-{
-	if [ "$1" = "$2" ]; then
-		return 0
-	fi
-	if [ "$1" = "" -o ! -d "$1" ]; then
-		echo safedirmove: source dir $1 is not valid
-		return 1
-	fi
-	if [ "$2" = "" -o -e "$2" ]; then
-		echo safedirmove: dest dir $2 is not valid
-		return 1
-	fi
-	if [ "$3" = "" -o -e "$3" ]; then
-		echo safedirmove: tmp dir $3 is not valid
-		return 1
-	fi
-	mkdir -p $3
-	mv $1/* $3/
-	rmdir $1
-	mkdir -p $2
-	mv $3/* $2/
-	rmdir $3
-	return 0
-}
-
-makedeb()
-{
-	SUPPLEMENT=$1
-	DIRNAME=$PKGNAME
-
-	if [ $SUPPLEMENT = 1 ]; then
-		PKGNAME=$PKGNAME\32
-		DEBARCH=amd64
-	fi
-
-	umask 022
-	rm -f $PKGNAME\_$VERSION\_$DEBARCH.deb
-	TMPDIR=`mktemp -d /tmp/$PKGNAME-build.XXXXXX`
-	mkdir $TMPDIR/DEBIAN
-
-	if [ $SUPPLEMENT = 1 ]; then
-		make install DESTDIR=$TMPDIR
-		rm -rf $TMPDIR$BINDIR
-		if [ "$DATAROOTDIR" != "$PREFIX" ]; then
-			rm -rf $TMPDIR$DATAROOTDIR
-		fi
-		if [ "$JAVADIR" != "" ]; then
-			rm -rf $TMPDIR$JAVADIR
-		fi
-		rm -rf $TMPDIR$DOCDIR
-		rm -rf $TMPDIR$INCLUDEDIR
-		rm -rf $TMPDIR$MANDIR
-	else
-		make install DESTDIR=$TMPDIR
-		if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$DOCDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/doc" ]; then
-			safedirmove $TMPDIR/$DOCDIR $TMPDIR/usr/share/doc/$PKGNAME-$VERSION $TMPDIR/__tmpdoc
-			ln -fs /usr/share/doc/$DIRNAME-$VERSION $TMPDIR$DOCDIR
-		fi
-	fi
-
-	SIZE=`du -s $TMPDIR | cut -f1`
-	(cat pkgscripts/deb-control | sed s/{__PKGNAME}/$PKGNAME/g \
-		| sed s/{__ARCH}/$DEBARCH/g | sed s/{__SIZE}/$SIZE/g \
-		> $TMPDIR/DEBIAN/control)
-
-	/sbin/ldconfig -n $TMPDIR$LIBDIR
-
-	$SUDO chown -Rh root:root $TMPDIR/*
-	dpkg -b $TMPDIR $PKGNAME\_$VERSION\_$DEBARCH.deb
-}
-
-PKGNAME=@PKGNAME@
-VERSION=@VERSION@
-DEBARCH=@DEBARCH@
-PREFIX=@CMAKE_INSTALL_PREFIX@
-BINDIR=@CMAKE_INSTALL_FULL_BINDIR@
-DATAROOTDIR=@CMAKE_INSTALL_FULL_DATAROOTDIR@
-DOCDIR=@CMAKE_INSTALL_FULL_DOCDIR@
-INCLUDEDIR=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-JAVADIR=@CMAKE_INSTALL_FULL_JAVADIR@
-LIBDIR=@CMAKE_INSTALL_FULL_LIBDIR@
-MANDIR=@CMAKE_INSTALL_FULL_MANDIR@
-
-if [ ! `uid` -eq 0 ]; then
-	SUDO=sudo
-fi
-
-makedeb 0
-if [ "$DEBARCH" = "i386" ]; then makedeb 1; fi
-
-exit
diff --git a/src/third_party/libjpeg-turbo/release/makemacpkg.in b/src/third_party/libjpeg-turbo/release/makemacpkg.in
deleted file mode 100644
index b0a2e23..0000000
--- a/src/third_party/libjpeg-turbo/release/makemacpkg.in
+++ /dev/null
@@ -1,268 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		rm -rf $TMPDIR
-	fi
-}
-
-safedirmove ()
-{
-	if [ "$1" = "$2" ]; then
-		return 0
-	fi
-	if [ "$1" = "" -o ! -d "$1" ]; then
-		echo safedirmove: source dir $1 is not valid
-		return 1
-	fi
-	if [ "$2" = "" -o -e "$2" ]; then
-		echo safedirmove: dest dir $2 is not valid
-		return 1
-	fi
-	if [ "$3" = "" -o -e "$3" ]; then
-		echo safedirmove: tmp dir $3 is not valid
-		return 1
-	fi
-	mkdir -p $3
-	mv $1/* $3/
-	rmdir $1
-	mkdir -p $2
-	mv $3/* $2/
-	rmdir $3
-	return 0
-}
-
-usage()
-{
-	echo "$0 [universal] [-lipo [path to lipo]]"
-	exit 1
-}
-
-UNIVERSAL=0
-
-PKGNAME=@PKGNAME@
-VERSION=@VERSION@
-BUILD=@BUILD@
-SRCDIR=@CMAKE_CURRENT_SOURCE_DIR@
-BUILDDIR32=@OSX_32BIT_BUILD@
-BUILDDIRARMV7=@IOS_ARMV7_BUILD@
-BUILDDIRARMV7S=@IOS_ARMV7S_BUILD@
-BUILDDIRARMV8=@IOS_ARMV8_BUILD@
-WITH_JAVA=@WITH_JAVA@
-LIPO=lipo
-
-PREFIX=@CMAKE_INSTALL_PREFIX@
-BINDIR=@CMAKE_INSTALL_FULL_BINDIR@
-DOCDIR=@CMAKE_INSTALL_FULL_DOCDIR@
-LIBDIR=@CMAKE_INSTALL_FULL_LIBDIR@
-
-LIBJPEG_DSO_NAME=libjpeg.@SO_MAJOR_VERSION@.@SO_AGE@.@SO_MINOR_VERSION@.dylib
-TURBOJPEG_DSO_NAME=libturbojpeg.@TURBOJPEG_SO_VERSION@.dylib
-
-while [ $# -gt 0 ]; do
-	case $1 in
-	-h*)
-		usage 0
-		;;
-	-lipo)
-		if [ $# -gt 1 ]; then
-			if [[ ! "$2" =~ -.* ]]; then
-				LIPO=$2;  shift
-			fi
-		fi
-		;;
-	universal)
-		UNIVERSAL=1
-		;;
-	esac
-	shift
-done
-
-if [ -f $PKGNAME-$VERSION.dmg ]; then
-	rm -f $PKGNAME-$VERSION.dmg
-fi
-
-umask 022
-TMPDIR=`mktemp -d /tmp/$PKGNAME-build.XXXXXX`
-PKGROOT=$TMPDIR/pkg/Package_Root
-mkdir -p $PKGROOT
-
-make install DESTDIR=$PKGROOT
-
-if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$DOCDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/doc" ]; then
-	mkdir -p $PKGROOT/Library/Documentation
-	safedirmove $PKGROOT$DOCDIR $PKGROOT/Library/Documentation/$PKGNAME $TMPDIR/__tmpdoc
-	ln -fs /Library/Documentation/$PKGNAME $PKGROOT$DOCDIR
-fi
-
-if [ $UNIVERSAL = 1 -a "$BUILDDIR32" != "" ]; then
-	if [ ! -d $BUILDDIR32 ]; then
-		echo ERROR: 32-bit build directory $BUILDDIR32 does not exist
-		exit 1
-	fi
-	if [ ! -f $BUILDDIR32/Makefile ]; then
-		echo ERROR: 32-bit build directory $BUILDDIR32 is not configured
-		exit 1
-	fi
-	mkdir -p $TMPDIR/dist.x86
-	pushd $BUILDDIR32
-	make install DESTDIR=$TMPDIR/dist.x86
-	popd
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$LIBDIR/$LIBJPEG_DSO_NAME \
-		-arch x86_64 $PKGROOT/$LIBDIR/$LIBJPEG_DSO_NAME \
-		-output $PKGROOT/$LIBDIR/$LIBJPEG_DSO_NAME
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$LIBDIR/libjpeg.a \
-		-arch x86_64 $PKGROOT/$LIBDIR/libjpeg.a \
-		-output $PKGROOT/$LIBDIR/libjpeg.a
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$LIBDIR/$TURBOJPEG_DSO_NAME \
-		-arch x86_64 $PKGROOT/$LIBDIR/$TURBOJPEG_DSO_NAME \
-		-output $PKGROOT/$LIBDIR/$TURBOJPEG_DSO_NAME
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$LIBDIR/libturbojpeg.a \
-		-arch x86_64 $PKGROOT/$LIBDIR/libturbojpeg.a \
-		-output $PKGROOT/$LIBDIR/libturbojpeg.a
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/cjpeg \
-		-arch x86_64 $PKGROOT/$BINDIR/cjpeg \
-		-output $PKGROOT/$BINDIR/cjpeg
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/djpeg \
-		-arch x86_64 $PKGROOT/$BINDIR/djpeg \
-		-output $PKGROOT/$BINDIR/djpeg
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/jpegtran \
-		-arch x86_64 $PKGROOT/$BINDIR/jpegtran \
-		-output $PKGROOT/$BINDIR/jpegtran
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/tjbench \
-		-arch x86_64 $PKGROOT/$BINDIR/tjbench \
-		-output $PKGROOT/$BINDIR/tjbench
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/rdjpgcom \
-		-arch x86_64 $PKGROOT/$BINDIR/rdjpgcom \
-		-output $PKGROOT/$BINDIR/rdjpgcom
-	$LIPO -create \
-		-arch i386 $TMPDIR/dist.x86/$BINDIR/wrjpgcom \
-		-arch x86_64 $PKGROOT/$BINDIR/wrjpgcom \
-		-output $PKGROOT/$BINDIR/wrjpgcom
-fi
-
-install_ios()
-{
-	BUILDDIR=$1
-	ARCHNAME=$2
-	DIRNAME=$3
-	LIPOARCH=$4
-
-	if [ ! -d $BUILDDIR ]; then
-		echo ERROR: $ARCHNAME build directory $BUILDDIR does not exist
-		exit 1
-	fi
-	if [ ! -f $BUILDDIR/Makefile ]; then
-		echo ERROR: $ARCHNAME build directory $BUILDDIR is not configured
-		exit 1
-	fi
-	mkdir -p $TMPDIR/dist.$DIRNAME
-	pushd $BUILDDIR
-	make install DESTDIR=$TMPDIR/dist.$DIRNAME
-	popd
-	$LIPO -create \
-		$PKGROOT/$LIBDIR/$LIBJPEG_DSO_NAME \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$LIBDIR/$LIBJPEG_DSO_NAME \
-		-output $PKGROOT/$LIBDIR/$LIBJPEG_DSO_NAME
-	$LIPO -create \
-		$PKGROOT/$LIBDIR/libjpeg.a \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$LIBDIR/libjpeg.a \
-		-output $PKGROOT/$LIBDIR/libjpeg.a
-	$LIPO -create \
-		$PKGROOT/$LIBDIR/$TURBOJPEG_DSO_NAME \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$LIBDIR/$TURBOJPEG_DSO_NAME \
-		-output $PKGROOT/$LIBDIR/$TURBOJPEG_DSO_NAME
-	$LIPO -create \
-		$PKGROOT/$LIBDIR/libturbojpeg.a \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$LIBDIR/libturbojpeg.a \
-		-output $PKGROOT/$LIBDIR/libturbojpeg.a
-	$LIPO -create \
-		$PKGROOT/$BINDIR/cjpeg \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/cjpeg \
-		-output $PKGROOT/$BINDIR/cjpeg
-	$LIPO -create \
-		$PKGROOT/$BINDIR/djpeg \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/djpeg \
-		-output $PKGROOT/$BINDIR/djpeg
-	$LIPO -create \
-		$PKGROOT/$BINDIR/jpegtran \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/jpegtran \
-		-output $PKGROOT/$BINDIR/jpegtran
-	$LIPO -create \
-		$PKGROOT/$BINDIR/tjbench \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/tjbench \
-		-output $PKGROOT/$BINDIR/tjbench
-	$LIPO -create \
-		$PKGROOT/$BINDIR/rdjpgcom \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/rdjpgcom \
-		-output $PKGROOT/$BINDIR/rdjpgcom
-	$LIPO -create \
-		$PKGROOT/$BINDIR/wrjpgcom \
-		-arch $LIPOARCH $TMPDIR/dist.$DIRNAME/$BINDIR/wrjpgcom \
-		-output $PKGROOT/$BINDIR/wrjpgcom
-}
-
-if [ $UNIVERSAL = 1 -a "$BUILDDIRARMV7" != "" ]; then
-	install_ios $BUILDDIRARMV7 ARMv7 armv7 arm
-fi
-
-if [ $UNIVERSAL = 1 -a "$BUILDDIRARMV7S" != "" ]; then
-	install_ios $BUILDDIRARMV7S ARMv7s armv7s arm
-fi
-
-if [ $UNIVERSAL = 1 -a "BUILDDIRARMV8" != "" ]; then
-	install_ios $BUILDDIRARMV8 ARMv8 armv8 arm64
-fi
-
-install_name_tool -id $LIBDIR/$LIBJPEG_DSO_NAME $PKGROOT/$LIBDIR/$LIBJPEG_DSO_NAME
-install_name_tool -id $LIBDIR/$TURBOJPEG_DSO_NAME $PKGROOT/$LIBDIR/$TURBOJPEG_DSO_NAME
-
-if [ $WITH_JAVA = 1 ]; then
-	ln -fs $TURBOJPEG_DSO_NAME $PKGROOT/$LIBDIR/libturbojpeg.jnilib
-fi
-if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$LIBDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/lib" ]; then
-	if [ ! -h $PKGROOT/$PREFIX/lib32 ]; then
-		ln -fs lib $PKGROOT/$PREFIX/lib32
-	fi
-	if [ ! -h $PKGROOT/$PREFIX/lib64 ]; then
-		ln -fs lib $PKGROOT/$PREFIX/lib64
-	fi
-fi
-
-mkdir -p $TMPDIR/pkg
-
-install -m 755 pkgscripts/uninstall $PKGROOT/$BINDIR/
-
-find $PKGROOT -type f | while read file; do xattr -c $file; done
-
-cp $SRCDIR/release/License.rtf $SRCDIR/release/Welcome.rtf $SRCDIR/release/ReadMe.txt $TMPDIR/pkg/
-
-mkdir $TMPDIR/dmg
-pkgbuild --root $PKGROOT --version $VERSION.$BUILD --identifier @PKGID@ \
-	$TMPDIR/pkg/$PKGNAME.pkg
-productbuild --distribution pkgscripts/Distribution.xml \
-	--package-path $TMPDIR/pkg/ --resources $TMPDIR/pkg/ \
-	$TMPDIR/dmg/$PKGNAME.pkg
-hdiutil create -fs HFS+ -volname $PKGNAME-$VERSION \
-	-srcfolder "$TMPDIR/dmg" $TMPDIR/$PKGNAME-$VERSION.dmg
-cp $TMPDIR/$PKGNAME-$VERSION.dmg .
-
-exit
diff --git a/src/third_party/libjpeg-turbo/release/makerpm.in b/src/third_party/libjpeg-turbo/release/makerpm.in
deleted file mode 100644
index fc3b1d4..0000000
--- a/src/third_party/libjpeg-turbo/release/makerpm.in
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		rm -rf $TMPDIR
-	fi
-}
-
-if [ -f @PKGNAME@-@VERSION@.@RPMARCH@.rpm ]; then
-	rm -f @PKGNAME@-@VERSION@.@RPMARCH@.rpm
-fi
-
-umask 022
-TMPDIR=`mktemp -d /tmp/@CMAKE_PROJECT_NAME@-build.XXXXXX`
-
-mkdir -p $TMPDIR/RPMS
-ln -fs `pwd` $TMPDIR/BUILD
-rpmbuild -bb --define "_blddir $TMPDIR/buildroot" --define "_topdir $TMPDIR" \
-	--target @RPMARCH@ pkgscripts/rpm.spec; \
-cp $TMPDIR/RPMS/@RPMARCH@/@PKGNAME@-@VERSION@-@BUILD@.@RPMARCH@.rpm \
-	@PKGNAME@-@VERSION@.@RPMARCH@.rpm
diff --git a/src/third_party/libjpeg-turbo/release/makesrpm.in b/src/third_party/libjpeg-turbo/release/makesrpm.in
deleted file mode 100644
index 84c39d4..0000000
--- a/src/third_party/libjpeg-turbo/release/makesrpm.in
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		rm -rf $TMPDIR
-	fi
-}
-
-PKGNAME=@PKGNAME@
-PROJECT=@CMAKE_PROJECT_NAME@
-VERSION=@VERSION@
-BUILD=@BUILD@
-
-if [ -f $PKGNAME-$VERSION.src.rpm ]; then
-	rm -f $PKGNAME-$VERSION.src.rpm
-fi
-
-umask 022
-TMPDIR=`mktemp -d /tmp/$PKGNAME-build.XXXXXX`
-
-mkdir -p $TMPDIR/RPMS
-mkdir -p $TMPDIR/SRPMS
-mkdir -p $TMPDIR/BUILD
-mkdir -p $TMPDIR/SOURCES
-mkdir -p $TMPDIR/SPECS
-
-if [ ! -f $PROJECT-$VERSION.tar.gz ]; then
-	echo "ERROR: $PROJECT-$VERSION.tar.gz does not exist."
-fi
-
-cp $PROJECT-$VERSION.tar.gz $TMPDIR/SOURCES/$PROJECT-$VERSION.tar.gz
-
-cat pkgscripts/rpm.spec | sed s/%{_blddir}/%{_tmppath}/g \
-	| sed s/#--\>//g > $TMPDIR/SPECS/$PKGNAME.spec
-
-rpmbuild -bs --define "_topdir $TMPDIR" $TMPDIR/SPECS/$PKGNAME.spec
-mv $TMPDIR/SRPMS/$PKGNAME-$VERSION-$BUILD.src.rpm $PKGNAME-$VERSION.src.rpm
-
-exit
diff --git a/src/third_party/libjpeg-turbo/release/maketarball.in b/src/third_party/libjpeg-turbo/release/maketarball.in
deleted file mode 100644
index 00a9c7e..0000000
--- a/src/third_party/libjpeg-turbo/release/maketarball.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-TMPDIR=
-SUDO=
-
-onexit()
-{
-	if [ ! "$TMPDIR" = "" ]; then
-		rm -rf $TMPDIR
-	fi
-}
-
-uid()
-{
-	id | cut -f2 -d = | cut -f1 -d \(;
-}
-
-PKGNAME=@PKGNAME@
-VERSION=@VERSION@
-ARCH=@CPU_TYPE@
-OS=@CMAKE_SYSTEM_NAME@
-PREFIX=@CMAKE_INSTALL_PREFIX@
-
-umask 022
-rm -f $PKGNAME-$VERSION-$OS-$ARCH.tar.bz2
-TMPDIR=`mktemp -d /tmp/$PKGNAME-build.XXXXXX`
-mkdir -p $TMPDIR/install
-
-make install DESTDIR=$TMPDIR/install
-echo tartest >$TMPDIR/tartest
-GNUTAR=0
-BSDTAR=0
-tar cf $TMPDIR/tartest.tar --owner=root --group=root -C $TMPDIR tartest >/dev/null 2>&1 && GNUTAR=1
-if [ "$GNUTAR" = "1" ]; then
-	tar cf - --owner=root --group=root -C $TMPDIR/install .$PREFIX | bzip2 -c >$PKGNAME-$VERSION-$OS-$ARCH.tar.bz2
-else
-	tar cf $TMPDIR/tartest.tar --uid 0 --gid 0 -C $TMPDIR tartest >/dev/null 2>&1 && BSDTAR=1
-	if [ "$BSDTAR" = "1" ]; then
-		tar cf - --uid=0 --gid=0 -C $TMPDIR/install .$PREFIX | bzip2 -c >$PKGNAME-$VERSION-$OS-$ARCH.tar.bz2
-	else
-		tar cf - -C $TMPDIR/install .$PREFIX | bzip2 -c >$PKGNAME-$VERSION-$OS-$ARCH.tar.bz2
-	fi
-fi
-
-exit
diff --git a/src/third_party/libjpeg-turbo/release/rpm.spec.in b/src/third_party/libjpeg-turbo/release/rpm.spec.in
deleted file mode 100644
index a22c5e1..0000000
--- a/src/third_party/libjpeg-turbo/release/rpm.spec.in
+++ /dev/null
@@ -1,221 +0,0 @@
-%define _prefix @CMAKE_INSTALL_PREFIX@
-%define _bindir @CMAKE_INSTALL_FULL_BINDIR@
-%define _datarootdir @CMAKE_INSTALL_FULL_DATAROOTDIR@
-%define _docdir %{_defaultdocdir}/%{name}-%{version}
-%define _includedir @CMAKE_INSTALL_FULL_INCLUDEDIR@
-%define _javadir @CMAKE_INSTALL_FULL_JAVADIR@
-%define _mandir @CMAKE_INSTALL_FULL_MANDIR@
-%define _enable_static @ENABLE_STATIC@
-%define _enable_shared @ENABLE_SHARED@
-%define _with_turbojpeg @WITH_TURBOJPEG@
-%define _with_java @WITH_JAVA@
-
-%if "%{?__isa_bits:1}" == "1"
-%define _bits %{__isa_bits}
-%else
-# RPM < 4.6
-%if "%{_lib}" == "lib64"
-%define _bits 64
-%else
-%define _bits 32
-%endif
-%endif
-
-#-->%if 1
-%if "%{_bits}" == "64"
-%define _libdir %{_exec_prefix}/lib64
-%else
-%if "%{_prefix}" == "/opt/libjpeg-turbo"
-%define _libdir %{_exec_prefix}/lib32
-%endif
-%endif
-#-->%else
-%define _libdir @CMAKE_INSTALL_FULL_LIBDIR@
-#-->%endif
-
-Summary: A SIMD-accelerated JPEG codec that provides both the libjpeg and TurboJPEG APIs
-Name: @PKGNAME@
-Version: @VERSION@
-Vendor: @PKGVENDOR@
-URL: @PKGURL@
-Group: System Environment/Libraries
-#-->Source0: http://prdownloads.sourceforge.net/@CMAKE_PROJECT_NAME@/@CMAKE_PROJECT_NAME@-%{version}.tar.gz
-Release: @BUILD@
-License: BSD-style
-BuildRoot: %{_blddir}/%{name}-buildroot-%{version}-%{release}
-Prereq: /sbin/ldconfig
-%if "%{_bits}" == "64"
-Provides: %{name} = %{version}-%{release}, @CMAKE_PROJECT_NAME@ = %{version}-%{release}, libturbojpeg.so()(64bit)
-%else
-Provides: %{name} = %{version}-%{release}, @CMAKE_PROJECT_NAME@ = %{version}-%{release}, libturbojpeg.so
-%endif
-
-%description
-libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
-AVX2, NEON, AltiVec) to accelerate baseline JPEG compression and decompression
-on x86, x86-64, ARM, and PowerPC systems, as well as progressive JPEG
-compression on x86 and x86-64 systems.  On such systems, libjpeg-turbo is
-generally 2-6x as fast as libjpeg, all else being equal.  On other types of
-systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
-virtue of its highly-optimized Huffman coding routines.  In many cases, the
-performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
-
-libjpeg-turbo implements both the traditional libjpeg API as well as the less
-powerful but more straightforward TurboJPEG API.  libjpeg-turbo also features
-colorspace extensions that allow it to compress from/decompress to 32-bit and
-big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
-interface.
-
-libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
-derivative of libjpeg v6b developed by Miyasaka Masaru.  The TigerVNC and
-VirtualGL projects made numerous enhancements to the codec in 2009, and in
-early 2010, libjpeg-turbo spun off into an independent project, with the goal
-of making high-speed JPEG compression/decompression technology available to a
-broader range of users and developers.
-
-#-->%prep
-#-->%setup -q -n @CMAKE_PROJECT_NAME@-%{version}
-
-#-->%build
-#-->cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ \
-#-->  -DBUILD=%{release} \
-#-->  -DCMAKE_INSTALL_BINDIR=%{_bindir} \
-#-->  -DCMAKE_INSTALL_DATAROOTDIR=%{_datarootdir} \
-#-->  -DCMAKE_INSTALL_DOCDIR=%{_docdir} \
-#-->  -DCMAKE_INSTALL_INCLUDEDIR=%{_includedir} \
-#-->  -DCMAKE_INSTALL_JAVADIR=%{_javadir} \
-#-->  -DCMAKE_INSTALL_LIBDIR=%{_libdir} \
-#-->  -DCMAKE_INSTALL_MANDIR=%{_mandir} \
-#-->  -DCMAKE_INSTALL_PREFIX=%{_prefix} \
-#-->  -DCMAKE_POSITION_INDEPENDENT_CODE=@CMAKE_POSITION_INDEPENDENT_CODE@ \
-#-->  -DENABLE_SHARED=@ENABLE_SHARED@ -DENABLE_STATIC=@ENABLE_STATIC@ \
-#-->  -DSO_MAJOR_VERSION=@SO_MAJOR_VERSION@ \
-#-->  -DSO_MINOR_VERSION=@SO_MINOR_VERSION@ \
-#-->  -DJPEG_LIB_VERSION=@JPEG_LIB_VERSION@ \
-#-->  -DREQUIRE_SIMD=@REQUIRE_SIMD@ \
-#-->  -DWITH_12BIT=@WITH_12BIT@ -DWITH_ARITH_DEC=@WITH_ARITH_DEC@ \
-#-->  -DWITH_ARITH_ENC=@WITH_ARITH_ENC@ -DWITH_JAVA=@WITH_JAVA@ \
-#-->  -DWITH_JPEG7=@WITH_JPEG7@ -DWITH_JPEG8=@WITH_JPEG8@ \
-#-->  -DWITH_MEM_SRCDST=@WITH_MEM_SRCDST@ -DWITH_SIMD=@WITH_SIMD@ \
-#-->  -DWITH_TURBOJPEG=@WITH_TURBOJPEG@ .
-#-->make DESTDIR=$RPM_BUILD_ROOT
-
-%install
-
-rm -rf $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-/sbin/ldconfig -n $RPM_BUILD_ROOT%{_libdir}
-
-#-->%if 0
-
-# This is only needed to support in-tree RPM generation via 'make rpm'.  When
-# building from a SRPM, we control where things are installed via CMake
-# variables.
-
-safedirmove ()
-{
-	if [ "$1" = "$2" ]; then
-		return 0
-	fi
-	if [ "$1" = "" -o ! -d "$1" ]; then
-		echo safedirmove: source dir $1 is not valid
-		return 1
-	fi
-	if [ "$2" = "" -o -e "$2" ]; then
-		echo safedirmove: dest dir $2 is not valid
-		return 1
-	fi
-	if [ "$3" = "" -o -e "$3" ]; then
-		echo safedirmove: tmp dir $3 is not valid
-		return 1
-	fi
-	mkdir -p $3
-	mv $1/* $3/
-	rmdir $1
-	mkdir -p $2
-	mv $3/* $2/
-	rmdir $3
-	return 0
-}
-
-LJT_DOCDIR=@CMAKE_INSTALL_FULL_DOCDIR@
-if [ ! "$LJT_DOCDIR" = "%{_docdir}" ]; then
-	safedirmove $RPM_BUILD_ROOT/$LJT_DOCDIR $RPM_BUILD_ROOT/%{_docdir} $RPM_BUILD_ROOT/__tmpdoc
-fi
-
-#-->%endif
-
-LJT_DOCDIR=@CMAKE_INSTALL_FULL_DOCDIR@
-if [ "%{_prefix}" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$LJT_DOCDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/doc" ]; then
-	ln -fs %{_docdir} $RPM_BUILD_ROOT/$LJT_DOCDIR
-fi
-
-%post -p /sbin/ldconfig
-
-%postun -p /sbin/ldconfig
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%dir %{_docdir}
-%doc %{_docdir}/*
-%dir %{_prefix}
-%if "%{_prefix}" == "@CMAKE_INSTALL_DEFAULT_PREFIX@" && "%{_docdir}" != "%{_prefix}/doc"
- %{_prefix}/doc
-%endif
-%dir %{_bindir}
-%{_bindir}/cjpeg
-%{_bindir}/djpeg
-%{_bindir}/jpegtran
-%if "%{_with_turbojpeg}" == "1"
- %{_bindir}/tjbench
-%endif
-%{_bindir}/rdjpgcom
-%{_bindir}/wrjpgcom
-%dir %{_libdir}
-%if "%{_enable_shared}" == "1"
- %{_libdir}/libjpeg.so.@SO_MAJOR_VERSION@.@SO_AGE@.@SO_MINOR_VERSION@
- %{_libdir}/libjpeg.so.@SO_MAJOR_VERSION@
- %{_libdir}/libjpeg.so
-%endif
-%if "%{_enable_static}" == "1"
- %{_libdir}/libjpeg.a
-%endif
-%{_libdir}/pkgconfig
-%{_libdir}/pkgconfig/libjpeg.pc
-%if "%{_with_turbojpeg}" == "1"
- %if "%{_enable_shared}" == "1" || "%{_with_java}" == "1"
-  %{_libdir}/libturbojpeg.so.@TURBOJPEG_SO_VERSION@
-  %{_libdir}/libturbojpeg.so.@TURBOJPEG_SO_MAJOR_VERSION@
-  %{_libdir}/libturbojpeg.so
- %endif
- %if "%{_enable_static}" == "1"
-  %{_libdir}/libturbojpeg.a
- %endif
- %{_libdir}/pkgconfig/libturbojpeg.pc
-%endif
-%dir %{_includedir}
-%{_includedir}/jconfig.h
-%{_includedir}/jerror.h
-%{_includedir}/jmorecfg.h
-%{_includedir}/jpeglib.h
-%if "%{_with_turbojpeg}" == "1"
- %{_includedir}/turbojpeg.h
-%endif
-%dir %{_mandir}
-%dir %{_mandir}/man1
-%{_mandir}/man1/cjpeg.1*
-%{_mandir}/man1/djpeg.1*
-%{_mandir}/man1/jpegtran.1*
-%{_mandir}/man1/rdjpgcom.1*
-%{_mandir}/man1/wrjpgcom.1*
-%if "%{_prefix}" != "%{_datarootdir}"
- %dir %{_datarootdir}
-%endif
-%if "%{_with_java}" == "1"
- %dir %{_javadir}
- %{_javadir}/turbojpeg.jar
-%endif
-%changelog
diff --git a/src/third_party/libjpeg-turbo/release/uninstall.in b/src/third_party/libjpeg-turbo/release/uninstall.in
deleted file mode 100644
index cf1ba77..0000000
--- a/src/third_party/libjpeg-turbo/release/uninstall.in
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (C)2009-2011, 2013, 2016 D. R. Commander.  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 the libjpeg-turbo Project 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 HOLDERS 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.
-
-#!/bin/sh
-
-if [ ! "`id -u`" = "0" ]; then
-	echo "ERROR: This script must be executed as root"
-	exit -1
-fi
-
-PKGNAME=@PKGNAME@
-PKGID=@PKGID@
-RECEIPT=/Library/Receipts/$PKGNAME.pkg
-
-LSBOM=
-if [ -d $RECEIPT ]; then
-	LSBOM='lsbom -s -f -l '$RECEIPT'/Contents/Archive.bom'
-else
-	LSBOM='pkgutil --files '$PKGID
-fi
-
-mylsbom()
-{
-	$LSBOM || (echo "ERROR: Could not list package contents"; exit -1)
-}
-
-echo Removing package files ...
-EXITSTATUS=0
-pushd /
-mylsbom | while read file; do
-	if [ ! -d "$file" ]; then rm "$file" 2>&1 || EXITSTATUS=-1; fi
-done
-popd
-
-echo Removing package directories ...
-PREFIX=@CMAKE_INSTALL_PREFIX@
-BINDIR=@CMAKE_INSTALL_FULL_BINDIR@
-DATAROOTDIR=@CMAKE_INSTALL_FULL_DATAROOTDIR@
-INCLUDEDIR=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-JAVADIR=@CMAKE_INSTALL_FULL_JAVADIR@
-LIBDIR=@CMAKE_INSTALL_FULL_LIBDIR@
-MANDIR=@CMAKE_INSTALL_FULL_MANDIR@
-
-if [ -d $BINDIR ]; then
-	rmdir $BINDIR 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $LIBDIR/pkgconfig ]; then
-	rmdir $LIBDIR/pkgconfig 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $LIBDIR ]; then
-	rmdir $LIBDIR 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $INCLUDEDIR ]; then
-	rmdir $INCLUDEDIR 2>&1 || EXITSTATUS=-1
-fi
-if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a "$LIBDIR" = "@CMAKE_INSTALL_DEFAULT_PREFIX@/lib" ]; then
-	if [ -h $LIBDIR\32 ]; then
-		rm $LIBDIR\32 2>&1 || EXITSTATUS=-1
-	fi
-	if [ -h $LIBDIR\64 ]; then
-		rm $LIBDIR\64 2>&1 || EXITSTATUS=-1
-	fi
-fi
-if [ -d $MANDIR/man1 ]; then
-	rmdir $MANDIR/man1 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $MANDIR ]; then
-	rmdir $MANDIR 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $JAVADIR ]; then
-	rmdir $JAVADIR 2>&1 || EXITSTATUS=-1
-fi
-if [ -d $DATAROOTDIR -a "$DATAROOTDIR" != "$PREFIX" ]; then
-	rmdir $DATAROOTDIR 2>&1 || EXITSTATUS=-1
-fi
-if [ "$PREFIX" = "@CMAKE_INSTALL_DEFAULT_PREFIX@" -a -h "$PREFIX/doc" ]; then
-	rm $PREFIX/doc 2>&1 || EXITSTATUS=-1
-fi
-rmdir $PREFIX 2>&1 || EXITSTATUS=-1
-rmdir /Library/Documentation/$PKGNAME 2>&1 || EXITSTATUS=-1
-
-if [ -d $RECEIPT ]; then
-	echo Removing package receipt ...
-	rm -r $RECEIPT 2>&1 || EXITSTATUS=-1
-else
-	echo Forgetting package $PKGID ...
-	pkgutil --forget $PKGID
-fi
-
-exit $EXITSTATUS
diff --git a/src/third_party/libjpeg-turbo/sharedlib/CMakeLists.txt b/src/third_party/libjpeg-turbo/sharedlib/CMakeLists.txt
deleted file mode 100755
index 2d60170..0000000
--- a/src/third_party/libjpeg-turbo/sharedlib/CMakeLists.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-# Anything that must be linked against the shared C library on Windows must
-# be built in this subdirectory, because CMake doesn't allow us to override
-# the compiler flags for each build type except at directory scope.  Note
-# to CMake developers:  Add a COMPILE_FLAGS_<CONFIG> target property, or
-# better yet, provide a friendly way of configuring a Windows target to use the
-# static C library.
-
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..)
-
-if(MSVC)
-  # Build all configurations against shared C library
-  foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
-    CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
-    if(${var} MATCHES "/MT")
-      string(REGEX REPLACE "/MT" "/MD" ${var} "${${var}}")
-    endif()
-  endforeach()
-endif()
-
-foreach(src ${JPEG_SOURCES})
-  set(JPEG_SRCS ${JPEG_SRCS} ../${src})
-endforeach()
-
-if(WITH_SIMD AND MSVC_IDE)
-  # This tells CMake that the "source" files haven't been generated yet
-  set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
-endif()
-
-if(WIN32)
-  if(WITH_MEM_SRCDST)
-    set(DEFFILE ../win/jpeg${SO_MAJOR_VERSION}-memsrcdst.def)
-  else()
-    set(DEFFILE ../win/jpeg${SO_MAJOR_VERSION}.def)
-  endif()
-endif()
-add_library(jpeg SHARED ${JPEG_SRCS} ${DEFFILE} $<TARGET_OBJECTS:simd>
-  ${SIMD_OBJS})
-
-set_target_properties(jpeg PROPERTIES SOVERSION ${SO_MAJOR_VERSION}
-  VERSION ${SO_MAJOR_VERSION}.${SO_AGE}.${SO_MINOR_VERSION})
-if(APPLE)
-  if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
-    set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
-  endif()
-  set_target_properties(jpeg PROPERTIES MACOSX_RPATH 1)
-endif()
-if(MAPFLAG)
-  set_target_properties(jpeg PROPERTIES
-    LINK_FLAGS "${MAPFLAG}${CMAKE_CURRENT_BINARY_DIR}/../libjpeg.map")
-endif()
-if(MSVC)
-  set_target_properties(jpeg PROPERTIES SUFFIX ${SO_MAJOR_VERSION}.dll)
-  # The jsimd_*.c file is built using /MT, so this prevents a linker warning.
-  set_target_properties(jpeg PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD")
-elseif(MINGW)
-  set_target_properties(jpeg PROPERTIES SUFFIX -${SO_MAJOR_VERSION}.dll)
-endif()
-
-if(WIN32)
-  set(USE_SETMODE "-DUSE_SETMODE")
-endif()
-if(WITH_12BIT)
-  set(COMPILE_FLAGS "-DGIF_SUPPORTED -DPPM_SUPPORTED ${USE_SETMODE}")
-else()
-  set(COMPILE_FLAGS "-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
-  set(CJPEG_BMP_SOURCES ../rdbmp.c ../rdtarga.c)
-  set(DJPEG_BMP_SOURCES ../wrbmp.c ../wrtarga.c)
-endif()
-
-add_executable(cjpeg ../cjpeg.c ../cdjpeg.c ../rdgif.c ../rdppm.c
-  ../rdswitch.c ${CJPEG_BMP_SOURCES})
-set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
-target_link_libraries(cjpeg jpeg)
-
-add_executable(djpeg ../djpeg.c ../cdjpeg.c ../rdcolmap.c ../rdswitch.c
-  ../wrgif.c ../wrppm.c ${DJPEG_BMP_SOURCES})
-set_property(TARGET djpeg PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
-target_link_libraries(djpeg jpeg)
-
-add_executable(jpegtran ../jpegtran.c ../cdjpeg.c ../rdswitch.c ../transupp.c)
-target_link_libraries(jpegtran jpeg)
-set_property(TARGET jpegtran PROPERTY COMPILE_FLAGS "${USE_SETMODE}")
-
-add_executable(jcstest ../jcstest.c)
-target_link_libraries(jcstest jpeg)
-
-install(TARGETS jpeg cjpeg djpeg jpegtran
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/src/third_party/libjpeg-turbo/simd/CMakeLists.txt b/src/third_party/libjpeg-turbo/simd/CMakeLists.txt
deleted file mode 100755
index 2468b1b..0000000
--- a/src/third_party/libjpeg-turbo/simd/CMakeLists.txt
+++ /dev/null
@@ -1,351 +0,0 @@
-macro(simd_fail message)
-  if(REQUIRE_SIMD)
-    message(FATAL_ERROR "${message}.")
-  else()
-    message(WARNING "${message}.  Performance will suffer.")
-    set(WITH_SIMD 0 PARENT_SCOPE)
-  endif()
-endmacro()
-
-
-###############################################################################
-# x86[-64] (NASM)
-###############################################################################
-
-if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386")
-
-set(CMAKE_ASM_NASM_FLAGS_DEBUG_INIT "-g")
-set(CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO_INIT "-g")
-
-# Allow the location of the NASM executable to be specified using the ASM_NASM
-# environment variable.  This should happen automatically, but unfortunately
-# enable_language(ASM_NASM) doesn't parse the ASM_NASM environment variable
-# until after CMAKE_ASM_NASM_COMPILER has been populated with the results of
-# searching for NASM or YASM in the PATH.
-if(NOT DEFINED CMAKE_ASM_NASM_COMPILER AND DEFINED ENV{ASM_NASM})
-  set(CMAKE_ASM_NASM_COMPILER $ENV{ASM_NASM})
-endif()
-
-if(CPU_TYPE STREQUAL "x86_64")
-  if(CYGWIN)
-    set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
-  endif()
-elseif(CPU_TYPE STREQUAL "i386")
-  if(BORLAND)
-    set(CMAKE_ASM_NASM_OBJECT_FORMAT obj)
-  elseif(CYGWIN)
-    set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
-  endif()
-endif()
-
-enable_language(ASM_NASM)
-message(STATUS "CMAKE_ASM_NASM_COMPILER = ${CMAKE_ASM_NASM_COMPILER}")
-
-if(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "macho*")
-  set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DMACHO")
-elseif(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "elf*")
-  set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DELF")
-  set(CMAKE_ASM_NASM_DEBUG_FORMAT "dwarf2")
-endif()
-if(CPU_TYPE STREQUAL "x86_64")
-  if(WIN32 OR CYGWIN)
-    set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN64")
-  endif()
-  set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -D__x86_64__")
-elseif(CPU_TYPE STREQUAL "i386")
-  if(BORLAND)
-    set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DOBJ32")
-  elseif(WIN32 OR CYGWIN)
-    set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN32")
-  endif()
-endif()
-
-message(STATUS "CMAKE_ASM_NASM_OBJECT_FORMAT = ${CMAKE_ASM_NASM_OBJECT_FORMAT}")
-
-if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
-  simd_fail("SIMD extensions disabled: could not determine NASM object format")
-  return()
-endif()
-
-get_filename_component(CMAKE_ASM_NASM_COMPILER_TYPE
-  "${CMAKE_ASM_NASM_COMPILER}" NAME_WE)
-if(CMAKE_ASM_NASM_COMPILER_TYPE MATCHES "yasm")
-  foreach(var CMAKE_ASM_NASM_FLAGS_DEBUG CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO)
-    if(${var} STREQUAL "-g")
-      if(CMAKE_ASM_NASM_DEBUG_FORMAT)
-        set_property(CACHE ${var} PROPERTY VALUE "-g ${CMAKE_ASM_NASM_DEBUG_FORMAT}")
-      else()
-        set_property(CACHE ${var} PROPERTY VALUE "")
-      endif()
-    endif()
-  endforeach()
-endif()
-
-if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
-  set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DPIC")
-endif()
-
-string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
-set(EFFECTIVE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} ${CMAKE_ASM_NASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-message(STATUS "CMAKE_ASM_NASM_FLAGS = ${EFFECTIVE_ASM_NASM_FLAGS}")
-
-set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_SOURCE_DIR}/nasm/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/${CPU_TYPE}/\"")
-
-set(GREP grep)
-if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
-  set(GREP ggrep)
-endif()
-add_custom_target(jsimdcfg COMMAND
-  ${CMAKE_C_COMPILER} -E -I${CMAKE_BINARY_DIR} -I${CMAKE_CURRENT_BINARY_DIR}
-    -I${CMAKE_CURRENT_SOURCE_DIR}
-    ${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc.h |
-  ${GREP} -E '^[\;%]|^\ %' | sed 's%_cpp_protection_%%' |
-  sed 's@% define@%define@g' >${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc)
-
-if(CPU_TYPE STREQUAL "x86_64")
-  set(SIMD_SOURCES x86_64/jsimdcpu.asm x86_64/jfdctflt-sse.asm
-    x86_64/jccolor-sse2.asm x86_64/jcgray-sse2.asm x86_64/jchuff-sse2.asm
-    x86_64/jcphuff-sse2.asm x86_64/jcsample-sse2.asm x86_64/jdcolor-sse2.asm
-    x86_64/jdmerge-sse2.asm x86_64/jdsample-sse2.asm x86_64/jfdctfst-sse2.asm
-    x86_64/jfdctint-sse2.asm x86_64/jidctflt-sse2.asm x86_64/jidctfst-sse2.asm
-    x86_64/jidctint-sse2.asm x86_64/jidctred-sse2.asm x86_64/jquantf-sse2.asm
-    x86_64/jquanti-sse2.asm
-    x86_64/jccolor-avx2.asm x86_64/jcgray-avx2.asm x86_64/jcsample-avx2.asm
-    x86_64/jdcolor-avx2.asm x86_64/jdmerge-avx2.asm x86_64/jdsample-avx2.asm
-    x86_64/jfdctint-avx2.asm x86_64/jidctint-avx2.asm x86_64/jquanti-avx2.asm)
-else()
-  set(SIMD_SOURCES i386/jsimdcpu.asm i386/jfdctflt-3dn.asm
-    i386/jidctflt-3dn.asm i386/jquant-3dn.asm
-    i386/jccolor-mmx.asm i386/jcgray-mmx.asm i386/jcsample-mmx.asm
-    i386/jdcolor-mmx.asm i386/jdmerge-mmx.asm i386/jdsample-mmx.asm
-    i386/jfdctfst-mmx.asm i386/jfdctint-mmx.asm i386/jidctfst-mmx.asm
-    i386/jidctint-mmx.asm i386/jidctred-mmx.asm i386/jquant-mmx.asm
-    i386/jfdctflt-sse.asm i386/jidctflt-sse.asm i386/jquant-sse.asm
-    i386/jccolor-sse2.asm i386/jcgray-sse2.asm i386/jchuff-sse2.asm
-    i386/jcphuff-sse2.asm i386/jcsample-sse2.asm i386/jdcolor-sse2.asm
-    i386/jdmerge-sse2.asm i386/jdsample-sse2.asm i386/jfdctfst-sse2.asm
-    i386/jfdctint-sse2.asm i386/jidctflt-sse2.asm i386/jidctfst-sse2.asm
-    i386/jidctint-sse2.asm i386/jidctred-sse2.asm i386/jquantf-sse2.asm
-    i386/jquanti-sse2.asm
-    i386/jccolor-avx2.asm i386/jcgray-avx2.asm i386/jcsample-avx2.asm
-    i386/jdcolor-avx2.asm i386/jdmerge-avx2.asm i386/jdsample-avx2.asm
-    i386/jfdctint-avx2.asm i386/jidctint-avx2.asm i386/jquanti-avx2.asm)
-endif()
-
-if(MSVC_IDE)
-  set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-  string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
-endif()
-
-file(GLOB INC_FILES nasm/*.inc)
-
-foreach(file ${SIMD_SOURCES})
-  set(OBJECT_DEPENDS "")
-  if(${file} MATCHES jccolor)
-    string(REGEX REPLACE "jccolor" "jccolext" DEPFILE ${file})
-    set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
-      ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
-  endif()
-  if(${file} MATCHES jcgray)
-    string(REGEX REPLACE "jcgray" "jcgryext" DEPFILE ${file})
-    set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
-      ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
-  endif()
-  if(${file} MATCHES jdcolor)
-    string(REGEX REPLACE "jdcolor" "jdcolext" DEPFILE ${file})
-    set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
-      ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
-  endif()
-  if(${file} MATCHES jdmerge)
-    string(REGEX REPLACE "jdmerge" "jdmrgext" DEPFILE ${file})
-    set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
-      ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
-  endif()
-  set(OBJECT_DEPENDS ${OBJECT_DEPENDS} ${INC_FILES})
-  if(MSVC_IDE)
-    # The CMake Visual Studio generators do not work properly with the ASM_NASM
-    # language, so we have to go rogue here and use a custom command like we
-    # did in prior versions of libjpeg-turbo.  (This is why we can't have nice
-    # things.)
-    string(REGEX REPLACE "${CPU_TYPE}/" "" filename ${file})
-    set(SIMD_OBJ ${OBJDIR}/${filename}.obj)
-    add_custom_command(OUTPUT ${SIMD_OBJ} DEPENDS ${file} ${OBJECT_DEPENDS}
-      COMMAND ${CMAKE_ASM_NASM_COMPILER} -f${CMAKE_ASM_NASM_OBJECT_FORMAT}
-        ${CMAKE_ASM_NASM_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
-        -o${SIMD_OBJ})
-    set(SIMD_OBJS ${SIMD_OBJS} ${SIMD_OBJ})
-  else()
-    set_source_files_properties(${file} PROPERTIES OBJECT_DEPENDS
-      "${OBJECT_DEPENDS}")
-  endif()
-endforeach()
-
-if(MSVC_IDE)
-  set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)
-  add_library(simd OBJECT ${CPU_TYPE}/jsimd.c)
-  add_custom_target(simd-objs DEPENDS ${SIMD_OBJS})
-  add_dependencies(simd simd-objs)
-else()
-  add_library(simd OBJECT ${SIMD_SOURCES} ${CPU_TYPE}/jsimd.c)
-endif()
-if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
-  set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
-endif()
-
-
-###############################################################################
-# ARM (GAS)
-###############################################################################
-
-elseif(CPU_TYPE STREQUAL "arm64" OR CPU_TYPE STREQUAL "arm")
-
-enable_language(ASM)
-
-set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ASM_FLAGS}")
-
-string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
-set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
-
-# Test whether we need gas-preprocessor.pl
-if(CPU_TYPE STREQUAL "arm")
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
-    .text
-    .fpu neon
-    .arch armv7a
-    .object_arch armv4
-    .arm
-    pld [r0]
-    vmovn.u16 d0, q0")
-else()
-  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
-    .text
-    MYVAR .req x0
-    movi v0.16b, #100
-    mov MYVAR, #100
-    .unreq MYVAR")
-endif()
-
-separate_arguments(CMAKE_ASM_FLAGS_SEP UNIX_COMMAND "${CMAKE_ASM_FLAGS}")
-
-execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS_SEP}
-    -x assembler-with-cpp -c ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
-  RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
-if(NOT RESULT EQUAL 0)
-  message(STATUS "GAS appears to be broken.  Trying gas-preprocessor.pl ...")
-  execute_process(COMMAND gas-preprocessor.pl ${CMAKE_ASM_COMPILER}
-      ${CMAKE_ASM_FLAGS_SEP} -x assembler-with-cpp -c
-      ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
-    RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
-  if(NOT RESULT EQUAL 0)
-    simd_fail("SIMD extensions disabled: GAS is not working properly")
-    return()
-  else()
-    message(STATUS "Using gas-preprocessor.pl")
-    configure_file(gas-preprocessor.in gas-preprocessor @ONLY)
-    set(CMAKE_ASM_COMPILER ${CMAKE_CURRENT_BINARY_DIR}/gas-preprocessor)
-  endif()
-else()
-  message(STATUS "GAS is working properly")
-endif()
-
-file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S)
-
-add_library(simd OBJECT ${CPU_TYPE}/jsimd_neon.S ${CPU_TYPE}/jsimd.c)
-
-if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
-  set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
-endif()
-
-
-###############################################################################
-# MIPS (GAS)
-###############################################################################
-
-elseif(CPU_TYPE STREQUAL "mips")
-
-enable_language(ASM)
-
-string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
-set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
-
-add_library(simd OBJECT ${CPU_TYPE}/jsimd_dspr2.S ${CPU_TYPE}/jsimd.c)
-
-if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
-  set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
-endif()
-
-###############################################################################
-# Loongson (Intrinsics)
-###############################################################################
-
-elseif(CPU_TYPE STREQUAL "loongson")
-
-set(SIMD_SOURCES loongson/jccolor-mmi.c loongson/jcsample-mmi.c
-  loongson/jdcolor-mmi.c loongson/jdsample-mmi.c loongson/jfdctint-mmi.c
-  loongson/jidctint-mmi.c loongson/jquanti-mmi.c)
-
-if(CMAKE_COMPILER_IS_GNUCC)
-  foreach(file ${SIMD_SOURCES})
-    set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
-      " -fno-strict-aliasing")
-  endforeach()
-endif()
-
-add_library(simd OBJECT ${SIMD_SOURCES} loongson/jsimd.c)
-
-if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
-  set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
-endif()
-
-###############################################################################
-# PowerPC (Intrinsics)
-###############################################################################
-
-elseif(CPU_TYPE STREQUAL "powerpc")
-
-set(CMAKE_REQUIRED_FLAGS -maltivec)
-
-check_c_source_compiles("
-  #include <altivec.h>
-  int main(void) {
-    __vector int vi = { 0, 0, 0, 0 };
-    int i[4];
-    vec_st(vi, 0, i);
-    return i[0];
-  }" HAVE_ALTIVEC)
-
-unset(CMAKE_REQUIRED_FLAGS)
-
-if(NOT HAVE_ALTIVEC)
-  simd_fail("SIMD extensions not available for this CPU (PowerPC SPE)")
-  return()
-endif()
-
-set(SIMD_SOURCES powerpc/jccolor-altivec.c powerpc/jcgray-altivec.c
-  powerpc/jcsample-altivec.c powerpc/jdcolor-altivec.c
-  powerpc/jdmerge-altivec.c powerpc/jdsample-altivec.c
-  powerpc/jfdctfst-altivec.c powerpc/jfdctint-altivec.c
-  powerpc/jidctfst-altivec.c powerpc/jidctint-altivec.c
-  powerpc/jquanti-altivec.c)
-
-set_source_files_properties(${SIMD_SOURCES} PROPERTIES
-  COMPILE_FLAGS -maltivec)
-
-add_library(simd OBJECT ${SIMD_SOURCES} powerpc/jsimd.c)
-
-if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
-  set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
-endif()
-
-
-###############################################################################
-# None
-###############################################################################
-
-else()
-
-simd_fail("SIMD extensions not available for this CPU (${CMAKE_SYSTEM_PROCESSOR})")
-
-endif() # CPU_TYPE
diff --git a/src/third_party/libjpeg-turbo/simd/arm/aarch32/jccolext-neon.c b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jccolext-neon.c
new file mode 100644
index 0000000..362102d
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jccolext-neon.c
@@ -0,0 +1,148 @@
+/*
+ * jccolext-neon.c - colorspace conversion (32-bit Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* This file is included by jccolor-neon.c */
+
+
+/* RGB -> YCbCr conversion is defined by the following equations:
+ *    Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
+ *    Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128
+ *    Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + 128
+ *
+ * Avoid floating point arithmetic by using shifted integer constants:
+ *    0.29899597 = 19595 * 2^-16
+ *    0.58700561 = 38470 * 2^-16
+ *    0.11399841 =  7471 * 2^-16
+ *    0.16874695 = 11059 * 2^-16
+ *    0.33125305 = 21709 * 2^-16
+ *    0.50000000 = 32768 * 2^-16
+ *    0.41868592 = 27439 * 2^-16
+ *    0.08131409 =  5329 * 2^-16
+ * These constants are defined in jccolor-neon.c
+ *
+ * We add the fixed-point equivalent of 0.5 to Cb and Cr, which effectively
+ * rounds up or down the result via integer truncation.
+ */
+
+void jsimd_rgb_ycc_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
+                                JSAMPIMAGE output_buf, JDIMENSION output_row,
+                                int num_rows)
+{
+  /* Pointer to RGB(X/A) input data */
+  JSAMPROW inptr;
+  /* Pointers to Y, Cb, and Cr output data */
+  JSAMPROW outptr0, outptr1, outptr2;
+  /* Allocate temporary buffer for final (image_width % 8) pixels in row. */
+  ALIGN(16) uint8_t tmp_buf[8 * RGB_PIXELSIZE];
+
+  /* Set up conversion constants. */
+#ifdef HAVE_VLD1_U16_X2
+  const uint16x4x2_t consts = vld1_u16_x2(jsimd_rgb_ycc_neon_consts);
+#else
+  /* GCC does not currently support the intrinsic vld1_<type>_x2(). */
+  const uint16x4_t consts1 = vld1_u16(jsimd_rgb_ycc_neon_consts);
+  const uint16x4_t consts2 = vld1_u16(jsimd_rgb_ycc_neon_consts + 4);
+  const uint16x4x2_t consts = { { consts1, consts2 } };
+#endif
+  const uint32x4_t scaled_128_5 = vdupq_n_u32((128 << 16) + 32767);
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    output_row++;
+
+    int cols_remaining = image_width;
+    for (; cols_remaining > 0; cols_remaining -= 8) {
+
+      /* To prevent buffer overread by the vector load instructions, the last
+       * (image_width % 8) columns of data are first memcopied to a temporary
+       * buffer large enough to accommodate the vector load.
+       */
+      if (cols_remaining < 8) {
+        memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
+        inptr = tmp_buf;
+      }
+
+#if RGB_PIXELSIZE == 4
+      uint8x8x4_t input_pixels = vld4_u8(inptr);
+#else
+      uint8x8x3_t input_pixels = vld3_u8(inptr);
+#endif
+      uint16x8_t r = vmovl_u8(input_pixels.val[RGB_RED]);
+      uint16x8_t g = vmovl_u8(input_pixels.val[RGB_GREEN]);
+      uint16x8_t b = vmovl_u8(input_pixels.val[RGB_BLUE]);
+
+      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
+      uint32x4_t y_low = vmull_lane_u16(vget_low_u16(r), consts.val[0], 0);
+      y_low = vmlal_lane_u16(y_low, vget_low_u16(g), consts.val[0], 1);
+      y_low = vmlal_lane_u16(y_low, vget_low_u16(b), consts.val[0], 2);
+      uint32x4_t y_high = vmull_lane_u16(vget_high_u16(r), consts.val[0], 0);
+      y_high = vmlal_lane_u16(y_high, vget_high_u16(g), consts.val[0], 1);
+      y_high = vmlal_lane_u16(y_high, vget_high_u16(b), consts.val[0], 2);
+
+      /* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128 */
+      uint32x4_t cb_low = scaled_128_5;
+      cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(r), consts.val[0], 3);
+      cb_low = vmlsl_lane_u16(cb_low, vget_low_u16(g), consts.val[1], 0);
+      cb_low = vmlal_lane_u16(cb_low, vget_low_u16(b), consts.val[1], 1);
+      uint32x4_t cb_high = scaled_128_5;
+      cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(r), consts.val[0], 3);
+      cb_high = vmlsl_lane_u16(cb_high, vget_high_u16(g), consts.val[1], 0);
+      cb_high = vmlal_lane_u16(cb_high, vget_high_u16(b), consts.val[1], 1);
+
+      /* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128 */
+      uint32x4_t cr_low = scaled_128_5;
+      cr_low = vmlal_lane_u16(cr_low, vget_low_u16(r), consts.val[1], 1);
+      cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(g), consts.val[1], 2);
+      cr_low = vmlsl_lane_u16(cr_low, vget_low_u16(b), consts.val[1], 3);
+      uint32x4_t cr_high = scaled_128_5;
+      cr_high = vmlal_lane_u16(cr_high, vget_high_u16(r), consts.val[1], 1);
+      cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(g), consts.val[1], 2);
+      cr_high = vmlsl_lane_u16(cr_high, vget_high_u16(b), consts.val[1], 3);
+
+      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
+      uint16x8_t y_u16 = vcombine_u16(vrshrn_n_u32(y_low, 16),
+                                      vrshrn_n_u32(y_high, 16));
+      /* Descale Cb values (right shift) and narrow to 16-bit. */
+      uint16x8_t cb_u16 = vcombine_u16(vshrn_n_u32(cb_low, 16),
+                                       vshrn_n_u32(cb_high, 16));
+      /* Descale Cr values (right shift) and narrow to 16-bit. */
+      uint16x8_t cr_u16 = vcombine_u16(vshrn_n_u32(cr_low, 16),
+                                       vshrn_n_u32(cr_high, 16));
+      /* Narrow Y, Cb, and Cr values to 8-bit and store to memory.  Buffer
+       * overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
+       */
+      vst1_u8(outptr0, vmovn_u16(y_u16));
+      vst1_u8(outptr1, vmovn_u16(cb_u16));
+      vst1_u8(outptr2, vmovn_u16(cr_u16));
+
+      /* Increment pointers. */
+      inptr += (8 * RGB_PIXELSIZE);
+      outptr0 += 8;
+      outptr1 += 8;
+      outptr2 += 8;
+    }
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/aarch32/jchuff-neon.c b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jchuff-neon.c
new file mode 100644
index 0000000..066fcdb
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jchuff-neon.c
@@ -0,0 +1,334 @@
+/*
+ * jchuff-neon.c - Huffman entropy encoding (32-bit Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
+ */
+
+#define JPEG_INTERNALS
+#include "../../../jinclude.h"
+#include "../../../jpeglib.h"
+#include "../../../jsimd.h"
+#include "../../../jdct.h"
+#include "../../../jsimddct.h"
+#include "../../jsimd.h"
+#include "../jchuff.h"
+#include "../neon-compat.h"
+
+#include <limits.h>
+
+#include <arm_neon.h>
+
+
+JOCTET *jsimd_huff_encode_one_block_neon(void *state, JOCTET *buffer,
+                                         JCOEFPTR block, int last_dc_val,
+                                         c_derived_tbl *dctbl,
+                                         c_derived_tbl *actbl)
+{
+  uint8_t block_nbits[DCTSIZE2];
+  uint16_t block_diff[DCTSIZE2];
+
+  /* Load rows of coefficients from DCT block in zig-zag order. */
+
+  /* Compute DC coefficient difference value. (F.1.1.5.1) */
+  int16x8_t row0 = vdupq_n_s16(block[0] - last_dc_val);
+  row0 = vld1q_lane_s16(block +  1, row0, 1);
+  row0 = vld1q_lane_s16(block +  8, row0, 2);
+  row0 = vld1q_lane_s16(block + 16, row0, 3);
+  row0 = vld1q_lane_s16(block +  9, row0, 4);
+  row0 = vld1q_lane_s16(block +  2, row0, 5);
+  row0 = vld1q_lane_s16(block +  3, row0, 6);
+  row0 = vld1q_lane_s16(block + 10, row0, 7);
+
+  int16x8_t row1 = vld1q_dup_s16(block + 17);
+  row1 = vld1q_lane_s16(block + 24, row1, 1);
+  row1 = vld1q_lane_s16(block + 32, row1, 2);
+  row1 = vld1q_lane_s16(block + 25, row1, 3);
+  row1 = vld1q_lane_s16(block + 18, row1, 4);
+  row1 = vld1q_lane_s16(block + 11, row1, 5);
+  row1 = vld1q_lane_s16(block +  4, row1, 6);
+  row1 = vld1q_lane_s16(block +  5, row1, 7);
+
+  int16x8_t row2 = vld1q_dup_s16(block + 12);
+  row2 = vld1q_lane_s16(block + 19, row2, 1);
+  row2 = vld1q_lane_s16(block + 26, row2, 2);
+  row2 = vld1q_lane_s16(block + 33, row2, 3);
+  row2 = vld1q_lane_s16(block + 40, row2, 4);
+  row2 = vld1q_lane_s16(block + 48, row2, 5);
+  row2 = vld1q_lane_s16(block + 41, row2, 6);
+  row2 = vld1q_lane_s16(block + 34, row2, 7);
+
+  int16x8_t row3 = vld1q_dup_s16(block + 27);
+  row3 = vld1q_lane_s16(block + 20, row3, 1);
+  row3 = vld1q_lane_s16(block + 13, row3, 2);
+  row3 = vld1q_lane_s16(block +  6, row3, 3);
+  row3 = vld1q_lane_s16(block +  7, row3, 4);
+  row3 = vld1q_lane_s16(block + 14, row3, 5);
+  row3 = vld1q_lane_s16(block + 21, row3, 6);
+  row3 = vld1q_lane_s16(block + 28, row3, 7);
+
+  int16x8_t abs_row0 = vabsq_s16(row0);
+  int16x8_t abs_row1 = vabsq_s16(row1);
+  int16x8_t abs_row2 = vabsq_s16(row2);
+  int16x8_t abs_row3 = vabsq_s16(row3);
+
+  int16x8_t row0_lz = vclzq_s16(abs_row0);
+  int16x8_t row1_lz = vclzq_s16(abs_row1);
+  int16x8_t row2_lz = vclzq_s16(abs_row2);
+  int16x8_t row3_lz = vclzq_s16(abs_row3);
+
+  /* Compute number of bits required to represent each coefficient. */
+  uint8x8_t row0_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row0_lz)));
+  uint8x8_t row1_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row1_lz)));
+  uint8x8_t row2_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row2_lz)));
+  uint8x8_t row3_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row3_lz)));
+
+  vst1_u8(block_nbits + 0 * DCTSIZE, row0_nbits);
+  vst1_u8(block_nbits + 1 * DCTSIZE, row1_nbits);
+  vst1_u8(block_nbits + 2 * DCTSIZE, row2_nbits);
+  vst1_u8(block_nbits + 3 * DCTSIZE, row3_nbits);
+
+  uint16x8_t row0_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row0, 15)),
+              vnegq_s16(row0_lz));
+  uint16x8_t row1_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row1, 15)),
+              vnegq_s16(row1_lz));
+  uint16x8_t row2_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row2, 15)),
+              vnegq_s16(row2_lz));
+  uint16x8_t row3_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row3, 15)),
+              vnegq_s16(row3_lz));
+
+  uint16x8_t row0_diff = veorq_u16(vreinterpretq_u16_s16(abs_row0), row0_mask);
+  uint16x8_t row1_diff = veorq_u16(vreinterpretq_u16_s16(abs_row1), row1_mask);
+  uint16x8_t row2_diff = veorq_u16(vreinterpretq_u16_s16(abs_row2), row2_mask);
+  uint16x8_t row3_diff = veorq_u16(vreinterpretq_u16_s16(abs_row3), row3_mask);
+
+  /* Store diff values for rows 0, 1, 2, and 3. */
+  vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
+  vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
+  vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
+  vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
+
+  /* Load last four rows of coefficients from DCT block in zig-zag order. */
+  int16x8_t row4 = vld1q_dup_s16(block + 35);
+  row4 = vld1q_lane_s16(block + 42, row4, 1);
+  row4 = vld1q_lane_s16(block + 49, row4, 2);
+  row4 = vld1q_lane_s16(block + 56, row4, 3);
+  row4 = vld1q_lane_s16(block + 57, row4, 4);
+  row4 = vld1q_lane_s16(block + 50, row4, 5);
+  row4 = vld1q_lane_s16(block + 43, row4, 6);
+  row4 = vld1q_lane_s16(block + 36, row4, 7);
+
+  int16x8_t row5 = vld1q_dup_s16(block + 29);
+  row5 = vld1q_lane_s16(block + 22, row5, 1);
+  row5 = vld1q_lane_s16(block + 15, row5, 2);
+  row5 = vld1q_lane_s16(block + 23, row5, 3);
+  row5 = vld1q_lane_s16(block + 30, row5, 4);
+  row5 = vld1q_lane_s16(block + 37, row5, 5);
+  row5 = vld1q_lane_s16(block + 44, row5, 6);
+  row5 = vld1q_lane_s16(block + 51, row5, 7);
+
+  int16x8_t row6 = vld1q_dup_s16(block + 58);
+  row6 = vld1q_lane_s16(block + 59, row6, 1);
+  row6 = vld1q_lane_s16(block + 52, row6, 2);
+  row6 = vld1q_lane_s16(block + 45, row6, 3);
+  row6 = vld1q_lane_s16(block + 38, row6, 4);
+  row6 = vld1q_lane_s16(block + 31, row6, 5);
+  row6 = vld1q_lane_s16(block + 39, row6, 6);
+  row6 = vld1q_lane_s16(block + 46, row6, 7);
+
+  int16x8_t row7 = vld1q_dup_s16(block + 53);
+  row7 = vld1q_lane_s16(block + 60, row7, 1);
+  row7 = vld1q_lane_s16(block + 61, row7, 2);
+  row7 = vld1q_lane_s16(block + 54, row7, 3);
+  row7 = vld1q_lane_s16(block + 47, row7, 4);
+  row7 = vld1q_lane_s16(block + 55, row7, 5);
+  row7 = vld1q_lane_s16(block + 62, row7, 6);
+  row7 = vld1q_lane_s16(block + 63, row7, 7);
+
+  int16x8_t abs_row4 = vabsq_s16(row4);
+  int16x8_t abs_row5 = vabsq_s16(row5);
+  int16x8_t abs_row6 = vabsq_s16(row6);
+  int16x8_t abs_row7 = vabsq_s16(row7);
+
+  int16x8_t row4_lz = vclzq_s16(abs_row4);
+  int16x8_t row5_lz = vclzq_s16(abs_row5);
+  int16x8_t row6_lz = vclzq_s16(abs_row6);
+  int16x8_t row7_lz = vclzq_s16(abs_row7);
+
+  /* Compute number of bits required to represent each coefficient. */
+  uint8x8_t row4_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row4_lz)));
+  uint8x8_t row5_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row5_lz)));
+  uint8x8_t row6_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row6_lz)));
+  uint8x8_t row7_nbits = vsub_u8(vdup_n_u8(16),
+                                 vmovn_u16(vreinterpretq_u16_s16(row7_lz)));
+
+  vst1_u8(block_nbits + 4 * DCTSIZE, row4_nbits);
+  vst1_u8(block_nbits + 5 * DCTSIZE, row5_nbits);
+  vst1_u8(block_nbits + 6 * DCTSIZE, row6_nbits);
+  vst1_u8(block_nbits + 7 * DCTSIZE, row7_nbits);
+
+  uint16x8_t row4_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row4, 15)),
+              vnegq_s16(row4_lz));
+  uint16x8_t row5_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row5, 15)),
+              vnegq_s16(row5_lz));
+  uint16x8_t row6_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row6, 15)),
+              vnegq_s16(row6_lz));
+  uint16x8_t row7_mask =
+    vshlq_u16(vreinterpretq_u16_s16(vshrq_n_s16(row7, 15)),
+              vnegq_s16(row7_lz));
+
+  uint16x8_t row4_diff = veorq_u16(vreinterpretq_u16_s16(abs_row4), row4_mask);
+  uint16x8_t row5_diff = veorq_u16(vreinterpretq_u16_s16(abs_row5), row5_mask);
+  uint16x8_t row6_diff = veorq_u16(vreinterpretq_u16_s16(abs_row6), row6_mask);
+  uint16x8_t row7_diff = veorq_u16(vreinterpretq_u16_s16(abs_row7), row7_mask);
+
+  /* Store diff values for rows 4, 5, 6, and 7. */
+  vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
+  vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
+  vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
+  vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
+
+  /* Construct bitmap to accelerate encoding of AC coefficients.  A set bit
+   * means that the corresponding coefficient != 0.
+   */
+  uint8x8_t row0_nbits_gt0 = vcgt_u8(row0_nbits, vdup_n_u8(0));
+  uint8x8_t row1_nbits_gt0 = vcgt_u8(row1_nbits, vdup_n_u8(0));
+  uint8x8_t row2_nbits_gt0 = vcgt_u8(row2_nbits, vdup_n_u8(0));
+  uint8x8_t row3_nbits_gt0 = vcgt_u8(row3_nbits, vdup_n_u8(0));
+  uint8x8_t row4_nbits_gt0 = vcgt_u8(row4_nbits, vdup_n_u8(0));
+  uint8x8_t row5_nbits_gt0 = vcgt_u8(row5_nbits, vdup_n_u8(0));
+  uint8x8_t row6_nbits_gt0 = vcgt_u8(row6_nbits, vdup_n_u8(0));
+  uint8x8_t row7_nbits_gt0 = vcgt_u8(row7_nbits, vdup_n_u8(0));
+
+  /* { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } */
+  const uint8x8_t bitmap_mask =
+    vreinterpret_u8_u64(vmov_n_u64(0x0102040810204080));
+
+  row0_nbits_gt0 = vand_u8(row0_nbits_gt0, bitmap_mask);
+  row1_nbits_gt0 = vand_u8(row1_nbits_gt0, bitmap_mask);
+  row2_nbits_gt0 = vand_u8(row2_nbits_gt0, bitmap_mask);
+  row3_nbits_gt0 = vand_u8(row3_nbits_gt0, bitmap_mask);
+  row4_nbits_gt0 = vand_u8(row4_nbits_gt0, bitmap_mask);
+  row5_nbits_gt0 = vand_u8(row5_nbits_gt0, bitmap_mask);
+  row6_nbits_gt0 = vand_u8(row6_nbits_gt0, bitmap_mask);
+  row7_nbits_gt0 = vand_u8(row7_nbits_gt0, bitmap_mask);
+
+  uint8x8_t bitmap_rows_10 = vpadd_u8(row1_nbits_gt0, row0_nbits_gt0);
+  uint8x8_t bitmap_rows_32 = vpadd_u8(row3_nbits_gt0, row2_nbits_gt0);
+  uint8x8_t bitmap_rows_54 = vpadd_u8(row5_nbits_gt0, row4_nbits_gt0);
+  uint8x8_t bitmap_rows_76 = vpadd_u8(row7_nbits_gt0, row6_nbits_gt0);
+  uint8x8_t bitmap_rows_3210 = vpadd_u8(bitmap_rows_32, bitmap_rows_10);
+  uint8x8_t bitmap_rows_7654 = vpadd_u8(bitmap_rows_76, bitmap_rows_54);
+  uint8x8_t bitmap = vpadd_u8(bitmap_rows_7654, bitmap_rows_3210);
+
+  /* Shift left to remove DC bit. */
+  bitmap = vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(bitmap), 1));
+  /* Move bitmap to 32-bit scalar registers. */
+  uint32_t bitmap_1_32 = vget_lane_u32(vreinterpret_u32_u8(bitmap), 1);
+  uint32_t bitmap_33_63 = vget_lane_u32(vreinterpret_u32_u8(bitmap), 0);
+
+  /* Set up state and bit buffer for output bitstream. */
+  working_state *state_ptr = (working_state *)state;
+  int free_bits = state_ptr->cur.free_bits;
+  size_t put_buffer = state_ptr->cur.put_buffer;
+
+  /* Encode DC coefficient. */
+
+  unsigned int nbits = block_nbits[0];
+  /* Emit Huffman-coded symbol and additional diff bits. */
+  unsigned int diff = block_diff[0];
+  PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits], diff)
+
+  /* Encode AC coefficients. */
+
+  unsigned int r = 0;  /* r = run length of zeros */
+  unsigned int i = 1;  /* i = number of coefficients encoded */
+  /* Code and size information for a run length of 16 zero coefficients */
+  const unsigned int code_0xf0 = actbl->ehufco[0xf0];
+  const unsigned int size_0xf0 = actbl->ehufsi[0xf0];
+
+  while (bitmap_1_32 != 0) {
+    r = BUILTIN_CLZ(bitmap_1_32);
+    i += r;
+    bitmap_1_32 <<= r;
+    nbits = block_nbits[i];
+    diff = block_diff[i];
+    while (r > 15) {
+      /* If run length > 15, emit special run-length-16 codes. */
+      PUT_BITS(code_0xf0, size_0xf0)
+      r -= 16;
+    }
+    /* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
+    unsigned int rs = (r << 4) + nbits;
+    PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
+    i++;
+    bitmap_1_32 <<= 1;
+  }
+
+  r = 33 - i;
+  i = 33;
+
+  while (bitmap_33_63 != 0) {
+    unsigned int leading_zeros = BUILTIN_CLZ(bitmap_33_63);
+    r += leading_zeros;
+    i += leading_zeros;
+    bitmap_33_63 <<= leading_zeros;
+    nbits = block_nbits[i];
+    diff = block_diff[i];
+    while (r > 15) {
+      /* If run length > 15, emit special run-length-16 codes. */
+      PUT_BITS(code_0xf0, size_0xf0)
+      r -= 16;
+    }
+    /* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
+    unsigned int rs = (r << 4) + nbits;
+    PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
+    r = 0;
+    i++;
+    bitmap_33_63 <<= 1;
+  }
+
+  /* If the last coefficient(s) were zero, emit an end-of-block (EOB) code.
+   * The value of RS for the EOB code is 0.
+   */
+  if (i != 64) {
+    PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
+  }
+
+  state_ptr->cur.put_buffer = put_buffer;
+  state_ptr->cur.free_bits = free_bits;
+
+  return buffer;
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jsimd.c b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jsimd.c
similarity index 67%
rename from src/third_party/libjpeg-turbo/simd/arm/jsimd.c
rename to src/third_party/libjpeg-turbo/simd/arm/aarch32/jsimd.c
index 3d31cb4..c286994 100644
--- a/src/third_party/libjpeg-turbo/simd/arm/jsimd.c
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch32/jsimd.c
@@ -5,6 +5,8 @@
  * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
  * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, D. R. Commander.
  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
+ * Copyright (C) 2019, Google LLC.
+ * Copyright (C) 2020, Arm Limited.
  *
  * Based on the x86 SIMD extension for IJG JPEG library,
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -12,16 +14,16 @@
  *
  * This file contains the interface between the "normal" portions
  * of the library and the SIMD implementations when running on a
- * 32-bit ARM architecture.
+ * 32-bit Arm architecture.
  */
 
 #define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
+#include "../../../jinclude.h"
+#include "../../../jpeglib.h"
+#include "../../../jsimd.h"
+#include "../../../jdct.h"
+#include "../../../jsimddct.h"
 #include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
 
 #ifdef STARBOARD
 #include "starboard/client_porting/poem/strings_poem.h"
@@ -36,7 +38,7 @@
 static unsigned int simd_support = ~0;
 static unsigned int simd_huffman = 1;
 
-#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
 #if !defined(STARBOARD)
 
 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
@@ -113,7 +115,7 @@
 #ifndef NO_GETENV
   char *env = NULL;
 #endif
-#if !defined(__ARM_NEON__) && defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+#if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
 #if !defined(STARBOARD)
   int bufsize = 1024; /* an initial guess for the line buffer size limit */
 #endif
@@ -128,7 +130,7 @@
   simd_support |= JSIMD_NEON;
 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
 #if !defined(STARBOARD)
-  /* We still have a chance to use NEON regardless of globally used
+  /* We still have a chance to use Neon regardless of globally used
    * -mcpu/-mfpu options passed to gcc by performing runtime detection via
    * /proc/cpuinfo parsing on linux/android */
   while (!parse_proc_cpuinfo(bufsize)) {
@@ -175,6 +177,19 @@
 GLOBAL(int)
 jsimd_can_rgb_gray(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -257,6 +272,37 @@
                        JSAMPIMAGE output_buf, JDIMENSION output_row,
                        int num_rows)
 {
+  void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
+
+  switch (cinfo->in_color_space) {
+  case JCS_EXT_RGB:
+    neonfct = jsimd_extrgb_gray_convert_neon;
+    break;
+  case JCS_EXT_RGBX:
+  case JCS_EXT_RGBA:
+    neonfct = jsimd_extrgbx_gray_convert_neon;
+    break;
+  case JCS_EXT_BGR:
+    neonfct = jsimd_extbgr_gray_convert_neon;
+    break;
+  case JCS_EXT_BGRX:
+  case JCS_EXT_BGRA:
+    neonfct = jsimd_extbgrx_gray_convert_neon;
+    break;
+  case JCS_EXT_XBGR:
+  case JCS_EXT_ABGR:
+    neonfct = jsimd_extxbgr_gray_convert_neon;
+    break;
+  case JCS_EXT_XRGB:
+  case JCS_EXT_ARGB:
+    neonfct = jsimd_extxrgb_gray_convert_neon;
+    break;
+  default:
+    neonfct = jsimd_extrgb_gray_convert_neon;
+    break;
+  }
+
+  neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
 }
 
 GLOBAL(void)
@@ -309,12 +355,38 @@
 GLOBAL(int)
 jsimd_can_h2v2_downsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_downsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -322,23 +394,50 @@
 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
 {
+  jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
+                             compptr->v_samp_factor, compptr->width_in_blocks,
+                             input_data, output_data);
 }
 
 GLOBAL(void)
 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
                       JSAMPARRAY input_data, JSAMPARRAY output_data)
 {
+  jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
+                             compptr->v_samp_factor, compptr->width_in_blocks,
+                             input_data, output_data);
 }
 
 GLOBAL(int)
 jsimd_can_h2v2_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -346,17 +445,32 @@
 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
+                           input_data, output_data_ptr);
 }
 
 GLOBAL(void)
 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
+                           input_data, output_data_ptr);
 }
 
 GLOBAL(int)
 jsimd_can_h2v2_fancy_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -377,10 +491,30 @@
   return 0;
 }
 
+GLOBAL(int)
+jsimd_can_h1v2_fancy_upsample(void)
+{
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
+  return 0;
+}
+
 GLOBAL(void)
 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
+                                 compptr->downsampled_width, input_data,
+                                 output_data_ptr);
 }
 
 GLOBAL(void)
@@ -392,15 +526,46 @@
                                  output_data_ptr);
 }
 
+GLOBAL(void)
+jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
+                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
+{
+  jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
+                                 compptr->downsampled_width, input_data,
+                                 output_data_ptr);
+}
+
 GLOBAL(int)
 jsimd_can_h2v2_merged_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_merged_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -408,12 +573,74 @@
 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
 {
+  void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
+
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGR:
+      neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
+      break;
+    default:
+      neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
+      break;
+  }
+
+  neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
 }
 
 GLOBAL(void)
 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
 {
+  void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
+
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGR:
+      neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
+      break;
+    default:
+      neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
+      break;
+  }
+
+  neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
 }
 
 GLOBAL(int)
@@ -459,6 +686,17 @@
 GLOBAL(int)
 jsimd_can_fdct_islow(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(DCTELEM) != 2)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -488,6 +726,7 @@
 GLOBAL(void)
 jsimd_fdct_islow(DCTELEM *data)
 {
+  jsimd_fdct_islow_neon(data);
 }
 
 GLOBAL(void)
@@ -707,6 +946,16 @@
 GLOBAL(int)
 jsimd_can_encode_mcu_AC_first_prepare(void)
 {
+  init_simd();
+
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JCOEF) != 2)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -715,11 +964,23 @@
                                   const int *jpeg_natural_order_start, int Sl,
                                   int Al, JCOEF *values, size_t *zerobits)
 {
+  jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
+                                         Sl, Al, values, zerobits);
 }
 
 GLOBAL(int)
 jsimd_can_encode_mcu_AC_refine_prepare(void)
 {
+  init_simd();
+
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JCOEF) != 2)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -728,5 +989,7 @@
                                    const int *jpeg_natural_order_start, int Sl,
                                    int Al, JCOEF *absvalues, size_t *bits)
 {
-  return 0;
+  return jsimd_encode_mcu_AC_refine_prepare_neon(block,
+                                                 jpeg_natural_order_start, Sl,
+                                                 Al, absvalues, bits);
 }
diff --git a/src/third_party/libjpeg-turbo/simd/arm/aarch64/jccolext-neon.c b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jccolext-neon.c
new file mode 100644
index 0000000..37130c2
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jccolext-neon.c
@@ -0,0 +1,316 @@
+/*
+ * jccolext-neon.c - colorspace conversion (64-bit Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* This file is included by jccolor-neon.c */
+
+
+/* RGB -> YCbCr conversion is defined by the following equations:
+ *    Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
+ *    Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128
+ *    Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + 128
+ *
+ * Avoid floating point arithmetic by using shifted integer constants:
+ *    0.29899597 = 19595 * 2^-16
+ *    0.58700561 = 38470 * 2^-16
+ *    0.11399841 =  7471 * 2^-16
+ *    0.16874695 = 11059 * 2^-16
+ *    0.33125305 = 21709 * 2^-16
+ *    0.50000000 = 32768 * 2^-16
+ *    0.41868592 = 27439 * 2^-16
+ *    0.08131409 =  5329 * 2^-16
+ * These constants are defined in jccolor-neon.c
+ *
+ * We add the fixed-point equivalent of 0.5 to Cb and Cr, which effectively
+ * rounds up or down the result via integer truncation.
+ */
+
+void jsimd_rgb_ycc_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
+                                JSAMPIMAGE output_buf, JDIMENSION output_row,
+                                int num_rows)
+{
+  /* Pointer to RGB(X/A) input data */
+  JSAMPROW inptr;
+  /* Pointers to Y, Cb, and Cr output data */
+  JSAMPROW outptr0, outptr1, outptr2;
+  /* Allocate temporary buffer for final (image_width % 16) pixels in row. */
+  ALIGN(16) uint8_t tmp_buf[16 * RGB_PIXELSIZE];
+
+  /* Set up conversion constants. */
+  const uint16x8_t consts = vld1q_u16(jsimd_rgb_ycc_neon_consts);
+  const uint32x4_t scaled_128_5 = vdupq_n_u32((128 << 16) + 32767);
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr0 = output_buf[0][output_row];
+    outptr1 = output_buf[1][output_row];
+    outptr2 = output_buf[2][output_row];
+    output_row++;
+
+    int cols_remaining = image_width;
+    for (; cols_remaining >= 16; cols_remaining -= 16) {
+
+#if RGB_PIXELSIZE == 4
+      uint8x16x4_t input_pixels = vld4q_u8(inptr);
+#else
+      uint8x16x3_t input_pixels = vld3q_u8(inptr);
+#endif
+      uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
+      uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
+
+      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
+      uint32x4_t y_ll = vmull_laneq_u16(vget_low_u16(r_l), consts, 0);
+      y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(g_l), consts, 1);
+      y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(b_l), consts, 2);
+      uint32x4_t y_lh = vmull_laneq_u16(vget_high_u16(r_l), consts, 0);
+      y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(g_l), consts, 1);
+      y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(b_l), consts, 2);
+      uint32x4_t y_hl = vmull_laneq_u16(vget_low_u16(r_h), consts, 0);
+      y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(g_h), consts, 1);
+      y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(b_h), consts, 2);
+      uint32x4_t y_hh = vmull_laneq_u16(vget_high_u16(r_h), consts, 0);
+      y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(g_h), consts, 1);
+      y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(b_h), consts, 2);
+
+      /* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128 */
+      uint32x4_t cb_ll = scaled_128_5;
+      cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(r_l), consts, 3);
+      cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(g_l), consts, 4);
+      cb_ll = vmlal_laneq_u16(cb_ll, vget_low_u16(b_l), consts, 5);
+      uint32x4_t cb_lh = scaled_128_5;
+      cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(r_l), consts, 3);
+      cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(g_l), consts, 4);
+      cb_lh = vmlal_laneq_u16(cb_lh, vget_high_u16(b_l), consts, 5);
+      uint32x4_t cb_hl = scaled_128_5;
+      cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(r_h), consts, 3);
+      cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(g_h), consts, 4);
+      cb_hl = vmlal_laneq_u16(cb_hl, vget_low_u16(b_h), consts, 5);
+      uint32x4_t cb_hh = scaled_128_5;
+      cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(r_h), consts, 3);
+      cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(g_h), consts, 4);
+      cb_hh = vmlal_laneq_u16(cb_hh, vget_high_u16(b_h), consts, 5);
+
+      /* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128 */
+      uint32x4_t cr_ll = scaled_128_5;
+      cr_ll = vmlal_laneq_u16(cr_ll, vget_low_u16(r_l), consts, 5);
+      cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(g_l), consts, 6);
+      cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(b_l), consts, 7);
+      uint32x4_t cr_lh = scaled_128_5;
+      cr_lh = vmlal_laneq_u16(cr_lh, vget_high_u16(r_l), consts, 5);
+      cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(g_l), consts, 6);
+      cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(b_l), consts, 7);
+      uint32x4_t cr_hl = scaled_128_5;
+      cr_hl = vmlal_laneq_u16(cr_hl, vget_low_u16(r_h), consts, 5);
+      cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(g_h), consts, 6);
+      cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(b_h), consts, 7);
+      uint32x4_t cr_hh = scaled_128_5;
+      cr_hh = vmlal_laneq_u16(cr_hh, vget_high_u16(r_h), consts, 5);
+      cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(g_h), consts, 6);
+      cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(b_h), consts, 7);
+
+      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
+      uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
+                                    vrshrn_n_u32(y_lh, 16));
+      uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
+                                    vrshrn_n_u32(y_hh, 16));
+      /* Descale Cb values (right shift) and narrow to 16-bit. */
+      uint16x8_t cb_l = vcombine_u16(vshrn_n_u32(cb_ll, 16),
+                                     vshrn_n_u32(cb_lh, 16));
+      uint16x8_t cb_h = vcombine_u16(vshrn_n_u32(cb_hl, 16),
+                                     vshrn_n_u32(cb_hh, 16));
+      /* Descale Cr values (right shift) and narrow to 16-bit. */
+      uint16x8_t cr_l = vcombine_u16(vshrn_n_u32(cr_ll, 16),
+                                     vshrn_n_u32(cr_lh, 16));
+      uint16x8_t cr_h = vcombine_u16(vshrn_n_u32(cr_hl, 16),
+                                     vshrn_n_u32(cr_hh, 16));
+      /* Narrow Y, Cb, and Cr values to 8-bit and store to memory.  Buffer
+       * overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
+       */
+      vst1q_u8(outptr0, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
+      vst1q_u8(outptr1, vcombine_u8(vmovn_u16(cb_l), vmovn_u16(cb_h)));
+      vst1q_u8(outptr2, vcombine_u8(vmovn_u16(cr_l), vmovn_u16(cr_h)));
+
+      /* Increment pointers. */
+      inptr += (16 * RGB_PIXELSIZE);
+      outptr0 += 16;
+      outptr1 += 16;
+      outptr2 += 16;
+    }
+
+    if (cols_remaining > 8) {
+      /* To prevent buffer overread by the vector load instructions, the last
+       * (image_width % 16) columns of data are first memcopied to a temporary
+       * buffer large enough to accommodate the vector load.
+       */
+      memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
+      inptr = tmp_buf;
+
+#if RGB_PIXELSIZE == 4
+      uint8x16x4_t input_pixels = vld4q_u8(inptr);
+#else
+      uint8x16x3_t input_pixels = vld3q_u8(inptr);
+#endif
+      uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
+      uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
+
+      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
+      uint32x4_t y_ll = vmull_laneq_u16(vget_low_u16(r_l), consts, 0);
+      y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(g_l), consts, 1);
+      y_ll = vmlal_laneq_u16(y_ll, vget_low_u16(b_l), consts, 2);
+      uint32x4_t y_lh = vmull_laneq_u16(vget_high_u16(r_l), consts, 0);
+      y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(g_l), consts, 1);
+      y_lh = vmlal_laneq_u16(y_lh, vget_high_u16(b_l), consts, 2);
+      uint32x4_t y_hl = vmull_laneq_u16(vget_low_u16(r_h), consts, 0);
+      y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(g_h), consts, 1);
+      y_hl = vmlal_laneq_u16(y_hl, vget_low_u16(b_h), consts, 2);
+      uint32x4_t y_hh = vmull_laneq_u16(vget_high_u16(r_h), consts, 0);
+      y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(g_h), consts, 1);
+      y_hh = vmlal_laneq_u16(y_hh, vget_high_u16(b_h), consts, 2);
+
+      /* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128 */
+      uint32x4_t cb_ll = scaled_128_5;
+      cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(r_l), consts, 3);
+      cb_ll = vmlsl_laneq_u16(cb_ll, vget_low_u16(g_l), consts, 4);
+      cb_ll = vmlal_laneq_u16(cb_ll, vget_low_u16(b_l), consts, 5);
+      uint32x4_t cb_lh = scaled_128_5;
+      cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(r_l), consts, 3);
+      cb_lh = vmlsl_laneq_u16(cb_lh, vget_high_u16(g_l), consts, 4);
+      cb_lh = vmlal_laneq_u16(cb_lh, vget_high_u16(b_l), consts, 5);
+      uint32x4_t cb_hl = scaled_128_5;
+      cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(r_h), consts, 3);
+      cb_hl = vmlsl_laneq_u16(cb_hl, vget_low_u16(g_h), consts, 4);
+      cb_hl = vmlal_laneq_u16(cb_hl, vget_low_u16(b_h), consts, 5);
+      uint32x4_t cb_hh = scaled_128_5;
+      cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(r_h), consts, 3);
+      cb_hh = vmlsl_laneq_u16(cb_hh, vget_high_u16(g_h), consts, 4);
+      cb_hh = vmlal_laneq_u16(cb_hh, vget_high_u16(b_h), consts, 5);
+
+      /* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128 */
+      uint32x4_t cr_ll = scaled_128_5;
+      cr_ll = vmlal_laneq_u16(cr_ll, vget_low_u16(r_l), consts, 5);
+      cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(g_l), consts, 6);
+      cr_ll = vmlsl_laneq_u16(cr_ll, vget_low_u16(b_l), consts, 7);
+      uint32x4_t cr_lh = scaled_128_5;
+      cr_lh = vmlal_laneq_u16(cr_lh, vget_high_u16(r_l), consts, 5);
+      cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(g_l), consts, 6);
+      cr_lh = vmlsl_laneq_u16(cr_lh, vget_high_u16(b_l), consts, 7);
+      uint32x4_t cr_hl = scaled_128_5;
+      cr_hl = vmlal_laneq_u16(cr_hl, vget_low_u16(r_h), consts, 5);
+      cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(g_h), consts, 6);
+      cr_hl = vmlsl_laneq_u16(cr_hl, vget_low_u16(b_h), consts, 7);
+      uint32x4_t cr_hh = scaled_128_5;
+      cr_hh = vmlal_laneq_u16(cr_hh, vget_high_u16(r_h), consts, 5);
+      cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(g_h), consts, 6);
+      cr_hh = vmlsl_laneq_u16(cr_hh, vget_high_u16(b_h), consts, 7);
+
+      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
+      uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
+                                    vrshrn_n_u32(y_lh, 16));
+      uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
+                                    vrshrn_n_u32(y_hh, 16));
+      /* Descale Cb values (right shift) and narrow to 16-bit. */
+      uint16x8_t cb_l = vcombine_u16(vshrn_n_u32(cb_ll, 16),
+                                     vshrn_n_u32(cb_lh, 16));
+      uint16x8_t cb_h = vcombine_u16(vshrn_n_u32(cb_hl, 16),
+                                     vshrn_n_u32(cb_hh, 16));
+      /* Descale Cr values (right shift) and narrow to 16-bit. */
+      uint16x8_t cr_l = vcombine_u16(vshrn_n_u32(cr_ll, 16),
+                                     vshrn_n_u32(cr_lh, 16));
+      uint16x8_t cr_h = vcombine_u16(vshrn_n_u32(cr_hl, 16),
+                                     vshrn_n_u32(cr_hh, 16));
+      /* Narrow Y, Cb, and Cr values to 8-bit and store to memory.  Buffer
+       * overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
+       */
+      vst1q_u8(outptr0, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
+      vst1q_u8(outptr1, vcombine_u8(vmovn_u16(cb_l), vmovn_u16(cb_h)));
+      vst1q_u8(outptr2, vcombine_u8(vmovn_u16(cr_l), vmovn_u16(cr_h)));
+
+    } else if (cols_remaining > 0) {
+      /* To prevent buffer overread by the vector load instructions, the last
+       * (image_width % 8) columns of data are first memcopied to a temporary
+       * buffer large enough to accommodate the vector load.
+       */
+      memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
+      inptr = tmp_buf;
+
+#if RGB_PIXELSIZE == 4
+      uint8x8x4_t input_pixels = vld4_u8(inptr);
+#else
+      uint8x8x3_t input_pixels = vld3_u8(inptr);
+#endif
+      uint16x8_t r = vmovl_u8(input_pixels.val[RGB_RED]);
+      uint16x8_t g = vmovl_u8(input_pixels.val[RGB_GREEN]);
+      uint16x8_t b = vmovl_u8(input_pixels.val[RGB_BLUE]);
+
+      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
+      uint32x4_t y_l = vmull_laneq_u16(vget_low_u16(r), consts, 0);
+      y_l = vmlal_laneq_u16(y_l, vget_low_u16(g), consts, 1);
+      y_l = vmlal_laneq_u16(y_l, vget_low_u16(b), consts, 2);
+      uint32x4_t y_h = vmull_laneq_u16(vget_high_u16(r), consts, 0);
+      y_h = vmlal_laneq_u16(y_h, vget_high_u16(g), consts, 1);
+      y_h = vmlal_laneq_u16(y_h, vget_high_u16(b), consts, 2);
+
+      /* Compute Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + 128 */
+      uint32x4_t cb_l = scaled_128_5;
+      cb_l = vmlsl_laneq_u16(cb_l, vget_low_u16(r), consts, 3);
+      cb_l = vmlsl_laneq_u16(cb_l, vget_low_u16(g), consts, 4);
+      cb_l = vmlal_laneq_u16(cb_l, vget_low_u16(b), consts, 5);
+      uint32x4_t cb_h = scaled_128_5;
+      cb_h = vmlsl_laneq_u16(cb_h, vget_high_u16(r), consts, 3);
+      cb_h = vmlsl_laneq_u16(cb_h, vget_high_u16(g), consts, 4);
+      cb_h = vmlal_laneq_u16(cb_h, vget_high_u16(b), consts, 5);
+
+      /* Compute Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128 */
+      uint32x4_t cr_l = scaled_128_5;
+      cr_l = vmlal_laneq_u16(cr_l, vget_low_u16(r), consts, 5);
+      cr_l = vmlsl_laneq_u16(cr_l, vget_low_u16(g), consts, 6);
+      cr_l = vmlsl_laneq_u16(cr_l, vget_low_u16(b), consts, 7);
+      uint32x4_t cr_h = scaled_128_5;
+      cr_h = vmlal_laneq_u16(cr_h, vget_high_u16(r), consts, 5);
+      cr_h = vmlsl_laneq_u16(cr_h, vget_high_u16(g), consts, 6);
+      cr_h = vmlsl_laneq_u16(cr_h, vget_high_u16(b), consts, 7);
+
+      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
+      uint16x8_t y_u16 = vcombine_u16(vrshrn_n_u32(y_l, 16),
+                                      vrshrn_n_u32(y_h, 16));
+      /* Descale Cb values (right shift) and narrow to 16-bit. */
+      uint16x8_t cb_u16 = vcombine_u16(vshrn_n_u32(cb_l, 16),
+                                       vshrn_n_u32(cb_h, 16));
+      /* Descale Cr values (right shift) and narrow to 16-bit. */
+      uint16x8_t cr_u16 = vcombine_u16(vshrn_n_u32(cr_l, 16),
+                                       vshrn_n_u32(cr_h, 16));
+      /* Narrow Y, Cb, and Cr values to 8-bit and store to memory.  Buffer
+       * overwrite is permitted up to the next multiple of ALIGN_SIZE bytes.
+       */
+      vst1_u8(outptr0, vmovn_u16(y_u16));
+      vst1_u8(outptr1, vmovn_u16(cb_u16));
+      vst1_u8(outptr2, vmovn_u16(cr_u16));
+    }
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/aarch64/jchuff-neon.c b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jchuff-neon.c
new file mode 100644
index 0000000..f13fd1b
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jchuff-neon.c
@@ -0,0 +1,403 @@
+/*
+ * jchuff-neon.c - Huffman entropy encoding (64-bit Arm Neon)
+ *
+ * Copyright (C) 2020-2021, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * NOTE: All referenced figures are from
+ * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
+ */
+
+#define JPEG_INTERNALS
+#include "../../../jinclude.h"
+#include "../../../jpeglib.h"
+#include "../../../jsimd.h"
+#include "../../../jdct.h"
+#include "../../../jsimddct.h"
+#include "../../jsimd.h"
+#include "../align.h"
+#include "../jchuff.h"
+#include "neon-compat.h"
+
+#include <limits.h>
+
+#include <arm_neon.h>
+
+
+ALIGN(16) static const uint8_t jsimd_huff_encode_one_block_consts[] = {
+    0,   1,   2,   3,  16,  17,  32,  33,
+   18,  19,   4,   5,   6,   7,  20,  21,
+   34,  35,  48,  49, 255, 255,  50,  51,
+   36,  37,  22,  23,   8,   9,  10,  11,
+  255, 255,   6,   7,  20,  21,  34,  35,
+   48,  49, 255, 255,  50,  51,  36,  37,
+   54,  55,  40,  41,  26,  27,  12,  13,
+   14,  15,  28,  29,  42,  43,  56,  57,
+    6,   7,  20,  21,  34,  35,  48,  49,
+   50,  51,  36,  37,  22,  23,   8,   9,
+   26,  27,  12,  13, 255, 255,  14,  15,
+   28,  29,  42,  43,  56,  57, 255, 255,
+   52,  53,  54,  55,  40,  41,  26,  27,
+   12,  13, 255, 255,  14,  15,  28,  29,
+   26,  27,  40,  41,  42,  43,  28,  29,
+   14,  15,  30,  31,  44,  45,  46,  47
+};
+
+JOCTET *jsimd_huff_encode_one_block_neon(void *state, JOCTET *buffer,
+                                         JCOEFPTR block, int last_dc_val,
+                                         c_derived_tbl *dctbl,
+                                         c_derived_tbl *actbl)
+{
+  uint16_t block_diff[DCTSIZE2];
+
+  /* Load lookup table indices for rows of zig-zag ordering. */
+#ifdef HAVE_VLD1Q_U8_X4
+  const uint8x16x4_t idx_rows_0123 =
+    vld1q_u8_x4(jsimd_huff_encode_one_block_consts + 0 * DCTSIZE);
+  const uint8x16x4_t idx_rows_4567 =
+    vld1q_u8_x4(jsimd_huff_encode_one_block_consts + 8 * DCTSIZE);
+#else
+  /* GCC does not currently support intrinsics vl1dq_<type>_x4(). */
+  const uint8x16x4_t idx_rows_0123 = { {
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 0 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 2 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 4 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 6 * DCTSIZE)
+  } };
+  const uint8x16x4_t idx_rows_4567 = { {
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 8 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 10 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 12 * DCTSIZE),
+    vld1q_u8(jsimd_huff_encode_one_block_consts + 14 * DCTSIZE)
+  } };
+#endif
+
+  /* Load 8x8 block of DCT coefficients. */
+#ifdef HAVE_VLD1Q_U8_X4
+  const int8x16x4_t tbl_rows_0123 =
+    vld1q_s8_x4((int8_t *)(block + 0 * DCTSIZE));
+  const int8x16x4_t tbl_rows_4567 =
+    vld1q_s8_x4((int8_t *)(block + 4 * DCTSIZE));
+#else
+  const int8x16x4_t tbl_rows_0123 = { {
+    vld1q_s8((int8_t *)(block + 0 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 1 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 2 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 3 * DCTSIZE))
+  } };
+  const int8x16x4_t tbl_rows_4567 = { {
+    vld1q_s8((int8_t *)(block + 4 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 5 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 6 * DCTSIZE)),
+    vld1q_s8((int8_t *)(block + 7 * DCTSIZE))
+  } };
+#endif
+
+  /* Initialise extra lookup tables. */
+  const int8x16x4_t tbl_rows_2345 = { {
+    tbl_rows_0123.val[2], tbl_rows_0123.val[3],
+    tbl_rows_4567.val[0], tbl_rows_4567.val[1]
+  } };
+  const int8x16x3_t tbl_rows_567 =
+    { { tbl_rows_4567.val[1], tbl_rows_4567.val[2], tbl_rows_4567.val[3] } };
+
+  /* Shuffle coefficients into zig-zag order. */
+  int16x8_t row0 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[0]));
+  int16x8_t row1 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[1]));
+  int16x8_t row2 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_2345, idx_rows_0123.val[2]));
+  int16x8_t row3 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_0123, idx_rows_0123.val[3]));
+  int16x8_t row4 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_4567, idx_rows_4567.val[0]));
+  int16x8_t row5 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_2345, idx_rows_4567.val[1]));
+  int16x8_t row6 =
+    vreinterpretq_s16_s8(vqtbl4q_s8(tbl_rows_4567, idx_rows_4567.val[2]));
+  int16x8_t row7 =
+    vreinterpretq_s16_s8(vqtbl3q_s8(tbl_rows_567, idx_rows_4567.val[3]));
+
+  /* Compute DC coefficient difference value (F.1.1.5.1). */
+  row0 = vsetq_lane_s16(block[0] - last_dc_val, row0, 0);
+  /* Initialize AC coefficient lanes not reachable by lookup tables. */
+  row1 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[0]),
+                                  0), row1, 2);
+  row2 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[1]),
+                                  4), row2, 0);
+  row2 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[2]),
+                                  0), row2, 5);
+  row5 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[1]),
+                                  7), row5, 2);
+  row5 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_4567.val[2]),
+                                  3), row5, 7);
+  row6 =
+    vsetq_lane_s16(vgetq_lane_s16(vreinterpretq_s16_s8(tbl_rows_0123.val[3]),
+                                  7), row6, 5);
+
+  /* DCT block is now in zig-zag order; start Huffman encoding process. */
+  int16x8_t abs_row0 = vabsq_s16(row0);
+  int16x8_t abs_row1 = vabsq_s16(row1);
+  int16x8_t abs_row2 = vabsq_s16(row2);
+  int16x8_t abs_row3 = vabsq_s16(row3);
+  int16x8_t abs_row4 = vabsq_s16(row4);
+  int16x8_t abs_row5 = vabsq_s16(row5);
+  int16x8_t abs_row6 = vabsq_s16(row6);
+  int16x8_t abs_row7 = vabsq_s16(row7);
+
+  /* For negative coeffs: diff = abs(coeff) -1 = ~abs(coeff) */
+  uint16x8_t row0_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row0, vshrq_n_s16(row0, 15)));
+  uint16x8_t row1_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row1, vshrq_n_s16(row1, 15)));
+  uint16x8_t row2_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row2, vshrq_n_s16(row2, 15)));
+  uint16x8_t row3_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row3, vshrq_n_s16(row3, 15)));
+  uint16x8_t row4_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row4, vshrq_n_s16(row4, 15)));
+  uint16x8_t row5_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row5, vshrq_n_s16(row5, 15)));
+  uint16x8_t row6_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row6, vshrq_n_s16(row6, 15)));
+  uint16x8_t row7_diff =
+    vreinterpretq_u16_s16(veorq_s16(abs_row7, vshrq_n_s16(row7, 15)));
+
+  /* Construct bitmap to accelerate encoding of AC coefficients.  A set bit
+   * means that the corresponding coefficient != 0.
+   */
+  uint8x8_t abs_row0_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row0),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row1_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row1),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row2_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row2),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row3_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row3),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row4_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row4),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row5_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row5),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row6_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row6),
+                                               vdupq_n_u16(0)));
+  uint8x8_t abs_row7_gt0 = vmovn_u16(vcgtq_u16(vreinterpretq_u16_s16(abs_row7),
+                                               vdupq_n_u16(0)));
+
+  /* { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 } */
+  const uint8x8_t bitmap_mask =
+    vreinterpret_u8_u64(vmov_n_u64(0x0102040810204080));
+
+  abs_row0_gt0 = vand_u8(abs_row0_gt0, bitmap_mask);
+  abs_row1_gt0 = vand_u8(abs_row1_gt0, bitmap_mask);
+  abs_row2_gt0 = vand_u8(abs_row2_gt0, bitmap_mask);
+  abs_row3_gt0 = vand_u8(abs_row3_gt0, bitmap_mask);
+  abs_row4_gt0 = vand_u8(abs_row4_gt0, bitmap_mask);
+  abs_row5_gt0 = vand_u8(abs_row5_gt0, bitmap_mask);
+  abs_row6_gt0 = vand_u8(abs_row6_gt0, bitmap_mask);
+  abs_row7_gt0 = vand_u8(abs_row7_gt0, bitmap_mask);
+
+  uint8x8_t bitmap_rows_10 = vpadd_u8(abs_row1_gt0, abs_row0_gt0);
+  uint8x8_t bitmap_rows_32 = vpadd_u8(abs_row3_gt0, abs_row2_gt0);
+  uint8x8_t bitmap_rows_54 = vpadd_u8(abs_row5_gt0, abs_row4_gt0);
+  uint8x8_t bitmap_rows_76 = vpadd_u8(abs_row7_gt0, abs_row6_gt0);
+  uint8x8_t bitmap_rows_3210 = vpadd_u8(bitmap_rows_32, bitmap_rows_10);
+  uint8x8_t bitmap_rows_7654 = vpadd_u8(bitmap_rows_76, bitmap_rows_54);
+  uint8x8_t bitmap_all = vpadd_u8(bitmap_rows_7654, bitmap_rows_3210);
+
+  /* Shift left to remove DC bit. */
+  bitmap_all =
+    vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(bitmap_all), 1));
+  /* Count bits set (number of non-zero coefficients) in bitmap. */
+  unsigned int non_zero_coefficients = vaddv_u8(vcnt_u8(bitmap_all));
+  /* Move bitmap to 64-bit scalar register. */
+  uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
+
+  /* Set up state and bit buffer for output bitstream. */
+  working_state *state_ptr = (working_state *)state;
+  int free_bits = state_ptr->cur.free_bits;
+  size_t put_buffer = state_ptr->cur.put_buffer;
+
+  /* Encode DC coefficient. */
+
+  /* Find nbits required to specify sign and amplitude of coefficient. */
+#if defined(_MSC_VER) && !defined(__clang__)
+  unsigned int lz = BUILTIN_CLZ(vgetq_lane_s16(abs_row0, 0));
+#else
+  unsigned int lz;
+  __asm__("clz %w0, %w1" : "=r"(lz) : "r"(vgetq_lane_s16(abs_row0, 0)));
+#endif
+  unsigned int nbits = 32 - lz;
+  /* Emit Huffman-coded symbol and additional diff bits. */
+  unsigned int diff = (unsigned int)(vgetq_lane_u16(row0_diff, 0) << lz) >> lz;
+  PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits], diff)
+
+  /* Encode AC coefficients. */
+
+  unsigned int r = 0;  /* r = run length of zeros */
+  unsigned int i = 1;  /* i = number of coefficients encoded */
+  /* Code and size information for a run length of 16 zero coefficients */
+  const unsigned int code_0xf0 = actbl->ehufco[0xf0];
+  const unsigned int size_0xf0 = actbl->ehufsi[0xf0];
+
+  /* The most efficient method of computing nbits and diff depends on the
+   * number of non-zero coefficients.  If the bitmap is not too sparse (> 8
+   * non-zero AC coefficients), it is beneficial to use Neon; else we compute
+   * nbits and diff on demand using scalar code.
+   */
+  if (non_zero_coefficients > 8) {
+    uint8_t block_nbits[DCTSIZE2];
+
+    int16x8_t row0_lz = vclzq_s16(abs_row0);
+    int16x8_t row1_lz = vclzq_s16(abs_row1);
+    int16x8_t row2_lz = vclzq_s16(abs_row2);
+    int16x8_t row3_lz = vclzq_s16(abs_row3);
+    int16x8_t row4_lz = vclzq_s16(abs_row4);
+    int16x8_t row5_lz = vclzq_s16(abs_row5);
+    int16x8_t row6_lz = vclzq_s16(abs_row6);
+    int16x8_t row7_lz = vclzq_s16(abs_row7);
+    /* Compute nbits needed to specify magnitude of each coefficient. */
+    uint8x8_t row0_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row0_lz)));
+    uint8x8_t row1_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row1_lz)));
+    uint8x8_t row2_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row2_lz)));
+    uint8x8_t row3_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row3_lz)));
+    uint8x8_t row4_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row4_lz)));
+    uint8x8_t row5_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row5_lz)));
+    uint8x8_t row6_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row6_lz)));
+    uint8x8_t row7_nbits = vsub_u8(vdup_n_u8(16),
+                                   vmovn_u16(vreinterpretq_u16_s16(row7_lz)));
+    /* Store nbits. */
+    vst1_u8(block_nbits + 0 * DCTSIZE, row0_nbits);
+    vst1_u8(block_nbits + 1 * DCTSIZE, row1_nbits);
+    vst1_u8(block_nbits + 2 * DCTSIZE, row2_nbits);
+    vst1_u8(block_nbits + 3 * DCTSIZE, row3_nbits);
+    vst1_u8(block_nbits + 4 * DCTSIZE, row4_nbits);
+    vst1_u8(block_nbits + 5 * DCTSIZE, row5_nbits);
+    vst1_u8(block_nbits + 6 * DCTSIZE, row6_nbits);
+    vst1_u8(block_nbits + 7 * DCTSIZE, row7_nbits);
+    /* Mask bits not required to specify sign and amplitude of diff. */
+    row0_diff = vshlq_u16(row0_diff, row0_lz);
+    row1_diff = vshlq_u16(row1_diff, row1_lz);
+    row2_diff = vshlq_u16(row2_diff, row2_lz);
+    row3_diff = vshlq_u16(row3_diff, row3_lz);
+    row4_diff = vshlq_u16(row4_diff, row4_lz);
+    row5_diff = vshlq_u16(row5_diff, row5_lz);
+    row6_diff = vshlq_u16(row6_diff, row6_lz);
+    row7_diff = vshlq_u16(row7_diff, row7_lz);
+    row0_diff = vshlq_u16(row0_diff, vnegq_s16(row0_lz));
+    row1_diff = vshlq_u16(row1_diff, vnegq_s16(row1_lz));
+    row2_diff = vshlq_u16(row2_diff, vnegq_s16(row2_lz));
+    row3_diff = vshlq_u16(row3_diff, vnegq_s16(row3_lz));
+    row4_diff = vshlq_u16(row4_diff, vnegq_s16(row4_lz));
+    row5_diff = vshlq_u16(row5_diff, vnegq_s16(row5_lz));
+    row6_diff = vshlq_u16(row6_diff, vnegq_s16(row6_lz));
+    row7_diff = vshlq_u16(row7_diff, vnegq_s16(row7_lz));
+    /* Store diff bits. */
+    vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
+    vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
+    vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
+    vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
+    vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
+    vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
+    vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
+    vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
+
+    while (bitmap != 0) {
+      r = BUILTIN_CLZLL(bitmap);
+      i += r;
+      bitmap <<= r;
+      nbits = block_nbits[i];
+      diff = block_diff[i];
+      while (r > 15) {
+        /* If run length > 15, emit special run-length-16 codes. */
+        PUT_BITS(code_0xf0, size_0xf0)
+        r -= 16;
+      }
+      /* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
+      unsigned int rs = (r << 4) + nbits;
+      PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
+      i++;
+      bitmap <<= 1;
+    }
+  } else if (bitmap != 0) {
+    uint16_t block_abs[DCTSIZE2];
+    /* Store absolute value of coefficients. */
+    vst1q_u16(block_abs + 0 * DCTSIZE, vreinterpretq_u16_s16(abs_row0));
+    vst1q_u16(block_abs + 1 * DCTSIZE, vreinterpretq_u16_s16(abs_row1));
+    vst1q_u16(block_abs + 2 * DCTSIZE, vreinterpretq_u16_s16(abs_row2));
+    vst1q_u16(block_abs + 3 * DCTSIZE, vreinterpretq_u16_s16(abs_row3));
+    vst1q_u16(block_abs + 4 * DCTSIZE, vreinterpretq_u16_s16(abs_row4));
+    vst1q_u16(block_abs + 5 * DCTSIZE, vreinterpretq_u16_s16(abs_row5));
+    vst1q_u16(block_abs + 6 * DCTSIZE, vreinterpretq_u16_s16(abs_row6));
+    vst1q_u16(block_abs + 7 * DCTSIZE, vreinterpretq_u16_s16(abs_row7));
+    /* Store diff bits. */
+    vst1q_u16(block_diff + 0 * DCTSIZE, row0_diff);
+    vst1q_u16(block_diff + 1 * DCTSIZE, row1_diff);
+    vst1q_u16(block_diff + 2 * DCTSIZE, row2_diff);
+    vst1q_u16(block_diff + 3 * DCTSIZE, row3_diff);
+    vst1q_u16(block_diff + 4 * DCTSIZE, row4_diff);
+    vst1q_u16(block_diff + 5 * DCTSIZE, row5_diff);
+    vst1q_u16(block_diff + 6 * DCTSIZE, row6_diff);
+    vst1q_u16(block_diff + 7 * DCTSIZE, row7_diff);
+
+    /* Same as above but must mask diff bits and compute nbits on demand. */
+    while (bitmap != 0) {
+      r = BUILTIN_CLZLL(bitmap);
+      i += r;
+      bitmap <<= r;
+      lz = BUILTIN_CLZ(block_abs[i]);
+      nbits = 32 - lz;
+      diff = (unsigned int)(block_diff[i] << lz) >> lz;
+      while (r > 15) {
+        /* If run length > 15, emit special run-length-16 codes. */
+        PUT_BITS(code_0xf0, size_0xf0)
+        r -= 16;
+      }
+      /* Emit Huffman symbol for run length / number of bits. (F.1.2.2.1) */
+      unsigned int rs = (r << 4) + nbits;
+      PUT_CODE(actbl->ehufco[rs], actbl->ehufsi[rs], diff)
+      i++;
+      bitmap <<= 1;
+    }
+  }
+
+  /* If the last coefficient(s) were zero, emit an end-of-block (EOB) code.
+   * The value of RS for the EOB code is 0.
+   */
+  if (i != 64) {
+    PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
+  }
+
+  state_ptr->cur.put_buffer = put_buffer;
+  state_ptr->cur.free_bits = free_bits;
+
+  return buffer;
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm64/jsimd.c b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jsimd.c
similarity index 70%
rename from src/third_party/libjpeg-turbo/simd/arm64/jsimd.c
rename to src/third_party/libjpeg-turbo/simd/arm/aarch64/jsimd.c
index 0e6c7b9..7e0c2e0 100644
--- a/src/third_party/libjpeg-turbo/simd/arm64/jsimd.c
+++ b/src/third_party/libjpeg-turbo/simd/arm/aarch64/jsimd.c
@@ -3,8 +3,9 @@
  *
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, D. R. Commander.
+ * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2020, D. R. Commander.
  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
+ * Copyright (C) 2020, Arm Limited.
  *
  * Based on the x86 SIMD extension for IJG JPEG library,
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -12,20 +13,27 @@
  *
  * This file contains the interface between the "normal" portions
  * of the library and the SIMD implementations when running on a
- * 64-bit ARM architecture.
+ * 64-bit Arm architecture.
  */
 
 #define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
+#include "../../../jinclude.h"
+#include "../../../jpeglib.h"
+#include "../../../jsimd.h"
+#include "../../../jdct.h"
+#include "../../../jsimddct.h"
 #include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
+#include "jconfigint.h"
 
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
+#ifdef STARBOARD
+#include "starboard/client_porting/poem/strings_poem.h"
+#include "starboard/client_porting/poem/string_poem.h"
+#include "starboard/configuration.h"
+#include "starboard/client_porting/poem/stdio_poem.h"
+#include "starboard/character.h"
+#else
+#include "starboard/client_porting/poem/stdio_poem.h"
+#endif
 
 #define JSIMD_FASTLD3  1
 #define JSIMD_FASTST3  2
@@ -37,6 +45,7 @@
                                     JSIMD_FASTTBL;
 
 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+#if !defined(STARBOARD)
 
 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
 
@@ -106,6 +115,7 @@
 }
 
 #endif
+#endif
 
 /*
  * Check what SIMD accelerations are supported.
@@ -114,8 +124,8 @@
  */
 
 /*
- * ARMv8 architectures support NEON extensions by default.
- * It is no longer optional as it was with ARMv7.
+ * Armv8 architectures support Neon extensions by default.
+ * It is no longer optional as it was with Armv7.
  */
 
 
@@ -126,8 +136,10 @@
   char *env = NULL;
 #endif
 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+#if !defined(STARBOARD)
   int bufsize = 1024; /* an initial guess for the line buffer size limit */
 #endif
+#endif
 
   if (simd_support != ~0U)
     return;
@@ -136,12 +148,14 @@
 
   simd_support |= JSIMD_NEON;
 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
+#if !defined(STARBOARD)
   while (!parse_proc_cpuinfo(bufsize)) {
     bufsize *= 2;
     if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
       break;
   }
 #endif
+#endif
 
 #ifndef NO_GETENV
   /* Force different settings through environment variables */
@@ -189,6 +203,19 @@
 GLOBAL(int)
 jsimd_can_rgb_gray(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -237,20 +264,28 @@
 
   switch (cinfo->in_color_space) {
   case JCS_EXT_RGB:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTLD3)
+#endif
       neonfct = jsimd_extrgb_ycc_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_extrgb_ycc_convert_neon_slowld3;
+#endif
     break;
   case JCS_EXT_RGBX:
   case JCS_EXT_RGBA:
     neonfct = jsimd_extrgbx_ycc_convert_neon;
     break;
   case JCS_EXT_BGR:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTLD3)
+#endif
       neonfct = jsimd_extbgr_ycc_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_extbgr_ycc_convert_neon_slowld3;
+#endif
     break;
   case JCS_EXT_BGRX:
   case JCS_EXT_BGRA:
@@ -265,10 +300,14 @@
     neonfct = jsimd_extxrgb_ycc_convert_neon;
     break;
   default:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTLD3)
+#endif
       neonfct = jsimd_extrgb_ycc_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_extrgb_ycc_convert_neon_slowld3;
+#endif
     break;
   }
 
@@ -280,6 +319,37 @@
                        JSAMPIMAGE output_buf, JDIMENSION output_row,
                        int num_rows)
 {
+  void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
+
+  switch (cinfo->in_color_space) {
+  case JCS_EXT_RGB:
+    neonfct = jsimd_extrgb_gray_convert_neon;
+    break;
+  case JCS_EXT_RGBX:
+  case JCS_EXT_RGBA:
+    neonfct = jsimd_extrgbx_gray_convert_neon;
+    break;
+  case JCS_EXT_BGR:
+    neonfct = jsimd_extbgr_gray_convert_neon;
+    break;
+  case JCS_EXT_BGRX:
+  case JCS_EXT_BGRA:
+    neonfct = jsimd_extbgrx_gray_convert_neon;
+    break;
+  case JCS_EXT_XBGR:
+  case JCS_EXT_ABGR:
+    neonfct = jsimd_extxbgr_gray_convert_neon;
+    break;
+  case JCS_EXT_XRGB:
+  case JCS_EXT_ARGB:
+    neonfct = jsimd_extxrgb_gray_convert_neon;
+    break;
+  default:
+    neonfct = jsimd_extrgb_gray_convert_neon;
+    break;
+  }
+
+  neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
 }
 
 GLOBAL(void)
@@ -291,20 +361,28 @@
 
   switch (cinfo->out_color_space) {
   case JCS_EXT_RGB:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTST3)
+#endif
       neonfct = jsimd_ycc_extrgb_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_ycc_extrgb_convert_neon_slowst3;
+#endif
     break;
   case JCS_EXT_RGBX:
   case JCS_EXT_RGBA:
     neonfct = jsimd_ycc_extrgbx_convert_neon;
     break;
   case JCS_EXT_BGR:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTST3)
+#endif
       neonfct = jsimd_ycc_extbgr_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_ycc_extbgr_convert_neon_slowst3;
+#endif
     break;
   case JCS_EXT_BGRX:
   case JCS_EXT_BGRA:
@@ -319,10 +397,14 @@
     neonfct = jsimd_ycc_extxrgb_convert_neon;
     break;
   default:
+#ifndef NEON_INTRINSICS
     if (simd_features & JSIMD_FASTST3)
+#endif
       neonfct = jsimd_ycc_extrgb_convert_neon;
+#ifndef NEON_INTRINSICS
     else
       neonfct = jsimd_ycc_extrgb_convert_neon_slowst3;
+#endif
     break;
   }
 
@@ -397,12 +479,33 @@
 GLOBAL(int)
 jsimd_can_h2v2_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -410,23 +513,66 @@
 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
+                           input_data, output_data_ptr);
 }
 
 GLOBAL(void)
 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
+                           input_data, output_data_ptr);
 }
 
 GLOBAL(int)
 jsimd_can_h2v2_fancy_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_fancy_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
+  return 0;
+}
+
+GLOBAL(int)
+jsimd_can_h1v2_fancy_upsample(void)
+{
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -434,23 +580,60 @@
 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
+                                 compptr->downsampled_width, input_data,
+                                 output_data_ptr);
 }
 
 GLOBAL(void)
 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
 {
+  jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
+                                 compptr->downsampled_width, input_data,
+                                 output_data_ptr);
+}
+
+GLOBAL(void)
+jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
+                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
+{
+  jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
+                                 compptr->downsampled_width, input_data,
+                                 output_data_ptr);
 }
 
 GLOBAL(int)
 jsimd_can_h2v2_merged_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
 GLOBAL(int)
 jsimd_can_h2v1_merged_upsample(void)
 {
+  init_simd();
+
+  /* The code is optimised for these values only */
+  if (BITS_IN_JSAMPLE != 8)
+    return 0;
+  if (sizeof(JDIMENSION) != 4)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -458,12 +641,74 @@
 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
 {
+  void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
+
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGR:
+      neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
+      break;
+    default:
+      neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
+      break;
+  }
+
+  neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
 }
 
 GLOBAL(void)
 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
 {
+  void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
+
+  switch (cinfo->out_color_space) {
+    case JCS_EXT_RGB:
+      neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
+      break;
+    case JCS_EXT_RGBX:
+    case JCS_EXT_RGBA:
+      neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGR:
+      neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_BGRX:
+    case JCS_EXT_BGRA:
+      neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
+      break;
+    case JCS_EXT_XBGR:
+    case JCS_EXT_ABGR:
+      neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
+      break;
+    case JCS_EXT_XRGB:
+    case JCS_EXT_ARGB:
+      neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
+      break;
+    default:
+      neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
+      break;
+  }
+
+  neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
 }
 
 GLOBAL(int)
@@ -762,17 +1007,33 @@
                             int last_dc_val, c_derived_tbl *dctbl,
                             c_derived_tbl *actbl)
 {
+#ifndef NEON_INTRINSICS
   if (simd_features & JSIMD_FASTTBL)
+#endif
     return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
                                             dctbl, actbl);
+#ifndef NEON_INTRINSICS
   else
     return jsimd_huff_encode_one_block_neon_slowtbl(state, buffer, block,
                                                     last_dc_val, dctbl, actbl);
+#endif
 }
 
 GLOBAL(int)
 jsimd_can_encode_mcu_AC_first_prepare(void)
 {
+  init_simd();
+
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JCOEF) != 2)
+    return 0;
+  if (SIZEOF_SIZE_T != 8)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -781,11 +1042,25 @@
                                   const int *jpeg_natural_order_start, int Sl,
                                   int Al, JCOEF *values, size_t *zerobits)
 {
+  jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
+                                         Sl, Al, values, zerobits);
 }
 
 GLOBAL(int)
 jsimd_can_encode_mcu_AC_refine_prepare(void)
 {
+  init_simd();
+
+  if (DCTSIZE != 8)
+    return 0;
+  if (sizeof(JCOEF) != 2)
+    return 0;
+  if (SIZEOF_SIZE_T != 8)
+    return 0;
+
+  if (simd_support & JSIMD_NEON)
+    return 1;
+
   return 0;
 }
 
@@ -794,5 +1069,7 @@
                                    const int *jpeg_natural_order_start, int Sl,
                                    int Al, JCOEF *absvalues, size_t *bits)
 {
-  return 0;
+  return jsimd_encode_mcu_AC_refine_prepare_neon(block,
+                                                 jpeg_natural_order_start,
+                                                 Sl, Al, absvalues, bits);
 }
diff --git a/src/third_party/libjpeg-turbo/simd/arm/align.h b/src/third_party/libjpeg-turbo/simd/arm/align.h
new file mode 100644
index 0000000..cff4241
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/align.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* How to obtain memory alignment for structures and variables */
+#if defined(_MSC_VER)
+#define ALIGN(alignment)  __declspec(align(alignment))
+#elif defined(__clang__) || defined(__GNUC__)
+#define ALIGN(alignment)  __attribute__((aligned(alignment)))
+#else
+#error "Unknown compiler"
+#endif
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jccolor-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jccolor-neon.c
new file mode 100644
index 0000000..9fcc62d
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jccolor-neon.c
@@ -0,0 +1,160 @@
+/*
+ * jccolor-neon.c - colorspace conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+#include "neon-compat.h"
+
+#include <arm_neon.h>
+
+
+/* RGB -> YCbCr conversion constants */
+
+#define F_0_298  19595
+#define F_0_587  38470
+#define F_0_113  7471
+#define F_0_168  11059
+#define F_0_331  21709
+#define F_0_500  32768
+#define F_0_418  27439
+#define F_0_081  5329
+
+ALIGN(16) static const uint16_t jsimd_rgb_ycc_neon_consts[] = {
+  F_0_298, F_0_587, F_0_113, F_0_168,
+  F_0_331, F_0_500, F_0_418, F_0_081
+};
+
+
+/* Include inline routines for colorspace extensions. */
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED  EXT_RGB_RED
+#define RGB_GREEN  EXT_RGB_GREEN
+#define RGB_BLUE  EXT_RGB_BLUE
+#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extrgb_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
+
+#define RGB_RED  EXT_RGBX_RED
+#define RGB_GREEN  EXT_RGBX_GREEN
+#define RGB_BLUE  EXT_RGBX_BLUE
+#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extrgbx_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
+
+#define RGB_RED  EXT_BGR_RED
+#define RGB_GREEN  EXT_BGR_GREEN
+#define RGB_BLUE  EXT_BGR_BLUE
+#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extbgr_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
+
+#define RGB_RED  EXT_BGRX_RED
+#define RGB_GREEN  EXT_BGRX_GREEN
+#define RGB_BLUE  EXT_BGRX_BLUE
+#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extbgrx_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
+
+#define RGB_RED  EXT_XBGR_RED
+#define RGB_GREEN  EXT_XBGR_GREEN
+#define RGB_BLUE  EXT_XBGR_BLUE
+#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extxbgr_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
+
+#define RGB_RED  EXT_XRGB_RED
+#define RGB_GREEN  EXT_XRGB_GREEN
+#define RGB_BLUE  EXT_XRGB_BLUE
+#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
+#define jsimd_rgb_ycc_convert_neon  jsimd_extxrgb_ycc_convert_neon
+#if defined(__aarch64__) || defined(_M_ARM64)
+#include "aarch64/jccolext-neon.c"
+#else
+#include "aarch32/jccolext-neon.c"
+#endif
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_ycc_convert_neon
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jcgray-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jcgray-neon.c
new file mode 100644
index 0000000..71c7b2d
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jcgray-neon.c
@@ -0,0 +1,120 @@
+/*
+ * jcgray-neon.c - grayscale colorspace conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+/* RGB -> Grayscale conversion constants */
+
+#define F_0_298  19595
+#define F_0_587  38470
+#define F_0_113  7471
+
+
+/* Include inline routines for colorspace extensions. */
+
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED  EXT_RGB_RED
+#define RGB_GREEN  EXT_RGB_GREEN
+#define RGB_BLUE  EXT_RGB_BLUE
+#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extrgb_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
+
+#define RGB_RED  EXT_RGBX_RED
+#define RGB_GREEN  EXT_RGBX_GREEN
+#define RGB_BLUE  EXT_RGBX_BLUE
+#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extrgbx_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
+
+#define RGB_RED  EXT_BGR_RED
+#define RGB_GREEN  EXT_BGR_GREEN
+#define RGB_BLUE  EXT_BGR_BLUE
+#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extbgr_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
+
+#define RGB_RED  EXT_BGRX_RED
+#define RGB_GREEN  EXT_BGRX_GREEN
+#define RGB_BLUE  EXT_BGRX_BLUE
+#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extbgrx_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
+
+#define RGB_RED  EXT_XBGR_RED
+#define RGB_GREEN  EXT_XBGR_GREEN
+#define RGB_BLUE  EXT_XBGR_BLUE
+#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extxbgr_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
+
+#define RGB_RED  EXT_XRGB_RED
+#define RGB_GREEN  EXT_XRGB_GREEN
+#define RGB_BLUE  EXT_XRGB_BLUE
+#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
+#define jsimd_rgb_gray_convert_neon  jsimd_extxrgb_gray_convert_neon
+#include "jcgryext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_rgb_gray_convert_neon
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jcgryext-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jcgryext-neon.c
new file mode 100644
index 0000000..416a738
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jcgryext-neon.c
@@ -0,0 +1,106 @@
+/*
+ * jcgryext-neon.c - grayscale colorspace conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* This file is included by jcgray-neon.c */
+
+
+/* RGB -> Grayscale conversion is defined by the following equation:
+ *    Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
+ *
+ * Avoid floating point arithmetic by using shifted integer constants:
+ *    0.29899597 = 19595 * 2^-16
+ *    0.58700561 = 38470 * 2^-16
+ *    0.11399841 =  7471 * 2^-16
+ * These constants are defined in jcgray-neon.c
+ *
+ * This is the same computation as the RGB -> Y portion of RGB -> YCbCr.
+ */
+
+void jsimd_rgb_gray_convert_neon(JDIMENSION image_width, JSAMPARRAY input_buf,
+                                 JSAMPIMAGE output_buf, JDIMENSION output_row,
+                                 int num_rows)
+{
+  JSAMPROW inptr;
+  JSAMPROW outptr;
+  /* Allocate temporary buffer for final (image_width % 16) pixels in row. */
+  ALIGN(16) uint8_t tmp_buf[16 * RGB_PIXELSIZE];
+
+  while (--num_rows >= 0) {
+    inptr = *input_buf++;
+    outptr = output_buf[0][output_row];
+    output_row++;
+
+    int cols_remaining = image_width;
+    for (; cols_remaining > 0; cols_remaining -= 16) {
+
+      /* To prevent buffer overread by the vector load instructions, the last
+       * (image_width % 16) columns of data are first memcopied to a temporary
+       * buffer large enough to accommodate the vector load.
+       */
+      if (cols_remaining < 16) {
+        memcpy(tmp_buf, inptr, cols_remaining * RGB_PIXELSIZE);
+        inptr = tmp_buf;
+      }
+
+#if RGB_PIXELSIZE == 4
+      uint8x16x4_t input_pixels = vld4q_u8(inptr);
+#else
+      uint8x16x3_t input_pixels = vld3q_u8(inptr);
+#endif
+      uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t r_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_RED]));
+      uint16x8_t g_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t g_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_GREEN]));
+      uint16x8_t b_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_BLUE]));
+      uint16x8_t b_h = vmovl_u8(vget_high_u8(input_pixels.val[RGB_BLUE]));
+
+      /* Compute Y = 0.29900 * R + 0.58700 * G + 0.11400 * B */
+      uint32x4_t y_ll = vmull_n_u16(vget_low_u16(r_l), F_0_298);
+      uint32x4_t y_lh = vmull_n_u16(vget_high_u16(r_l), F_0_298);
+      uint32x4_t y_hl = vmull_n_u16(vget_low_u16(r_h), F_0_298);
+      uint32x4_t y_hh = vmull_n_u16(vget_high_u16(r_h), F_0_298);
+      y_ll = vmlal_n_u16(y_ll, vget_low_u16(g_l), F_0_587);
+      y_lh = vmlal_n_u16(y_lh, vget_high_u16(g_l), F_0_587);
+      y_hl = vmlal_n_u16(y_hl, vget_low_u16(g_h), F_0_587);
+      y_hh = vmlal_n_u16(y_hh, vget_high_u16(g_h), F_0_587);
+      y_ll = vmlal_n_u16(y_ll, vget_low_u16(b_l), F_0_113);
+      y_lh = vmlal_n_u16(y_lh, vget_high_u16(b_l), F_0_113);
+      y_hl = vmlal_n_u16(y_hl, vget_low_u16(b_h), F_0_113);
+      y_hh = vmlal_n_u16(y_hh, vget_high_u16(b_h), F_0_113);
+
+      /* Descale Y values (rounding right shift) and narrow to 16-bit. */
+      uint16x8_t y_l = vcombine_u16(vrshrn_n_u32(y_ll, 16),
+                                    vrshrn_n_u32(y_lh, 16));
+      uint16x8_t y_h = vcombine_u16(vrshrn_n_u32(y_hl, 16),
+                                    vrshrn_n_u32(y_hh, 16));
+
+      /* Narrow Y values to 8-bit and store to memory.  Buffer overwrite is
+       * permitted up to the next multiple of ALIGN_SIZE bytes.
+       */
+      vst1q_u8(outptr, vcombine_u8(vmovn_u16(y_l), vmovn_u16(y_h)));
+
+      /* Increment pointers. */
+      inptr += (16 * RGB_PIXELSIZE);
+      outptr += 16;
+    }
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jchuff.h b/src/third_party/libjpeg-turbo/simd/arm/jchuff.h
new file mode 100644
index 0000000..2fbd252
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jchuff.h
@@ -0,0 +1,131 @@
+/*
+ * jchuff.h
+ *
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2009, 2018, 2021, D. R. Commander.
+ * Copyright (C) 2018, Matthias Räncker.
+ * Copyright (C) 2020-2021, Arm Limited.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ */
+
+/* Expanded entropy encoder object for Huffman encoding.
+ *
+ * The savable_state subrecord contains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+#define BIT_BUF_SIZE  64
+#else
+#define BIT_BUF_SIZE  32
+#endif
+
+typedef struct {
+  size_t put_buffer;                    /* current bit accumulation buffer */
+  int free_bits;                        /* # of bits available in it */
+  int last_dc_val[MAX_COMPS_IN_SCAN];   /* last DC coef for each component */
+} savable_state;
+
+typedef struct {
+  JOCTET *next_output_byte;     /* => next byte to write in buffer */
+  size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
+  savable_state cur;            /* Current bit buffer & DC state */
+  j_compress_ptr cinfo;         /* dump_buffer needs access to this */
+  int simd;
+} working_state;
+
+/* Outputting bits to the file */
+
+/* Output byte b and, speculatively, an additional 0 byte. 0xFF must be encoded
+ * as 0xFF 0x00, so the output buffer pointer is advanced by 2 if the byte is
+ * 0xFF.  Otherwise, the output buffer pointer is advanced by 1, and the
+ * speculative 0 byte will be overwritten by the next byte.
+ */
+#define EMIT_BYTE(b) { \
+  buffer[0] = (JOCTET)(b); \
+  buffer[1] = 0; \
+  buffer -= -2 + ((JOCTET)(b) < 0xFF); \
+}
+
+/* Output the entire bit buffer.  If there are no 0xFF bytes in it, then write
+ * directly to the output buffer.  Otherwise, use the EMIT_BYTE() macro to
+ * encode 0xFF as 0xFF 0x00.
+ */
+#if defined(__aarch64__) || defined(_M_ARM64)
+
+#define FLUSH() { \
+  if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
+    EMIT_BYTE(put_buffer >> 56) \
+    EMIT_BYTE(put_buffer >> 48) \
+    EMIT_BYTE(put_buffer >> 40) \
+    EMIT_BYTE(put_buffer >> 32) \
+    EMIT_BYTE(put_buffer >> 24) \
+    EMIT_BYTE(put_buffer >> 16) \
+    EMIT_BYTE(put_buffer >>  8) \
+    EMIT_BYTE(put_buffer      ) \
+  } else { \
+    *((uint64_t *)buffer) = BUILTIN_BSWAP64(put_buffer); \
+    buffer += 8; \
+  } \
+}
+
+#else
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#define SPLAT() { \
+  buffer[0] = (JOCTET)(put_buffer >> 24); \
+  buffer[1] = (JOCTET)(put_buffer >> 16); \
+  buffer[2] = (JOCTET)(put_buffer >>  8); \
+  buffer[3] = (JOCTET)(put_buffer      ); \
+  buffer += 4; \
+}
+#else
+#define SPLAT() { \
+  put_buffer = __builtin_bswap32(put_buffer); \
+  __asm__("str %1, [%0], #4" : "+r" (buffer) : "r" (put_buffer)); \
+}
+#endif
+
+#define FLUSH() { \
+  if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
+    EMIT_BYTE(put_buffer >> 24) \
+    EMIT_BYTE(put_buffer >> 16) \
+    EMIT_BYTE(put_buffer >>  8) \
+    EMIT_BYTE(put_buffer      ) \
+  } else { \
+    SPLAT(); \
+  } \
+}
+
+#endif
+
+/* Fill the bit buffer to capacity with the leading bits from code, then output
+ * the bit buffer and put the remaining bits from code into the bit buffer.
+ */
+#define PUT_AND_FLUSH(code, size) { \
+  put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
+  FLUSH() \
+  free_bits += BIT_BUF_SIZE; \
+  put_buffer = code; \
+}
+
+/* Insert code into the bit buffer and output the bit buffer if needed.
+ * NOTE: We can't flush with free_bits == 0, since the left shift in
+ * PUT_AND_FLUSH() would have undefined behavior.
+ */
+#define PUT_BITS(code, size) { \
+  free_bits -= size; \
+  if (free_bits < 0) \
+    PUT_AND_FLUSH(code, size) \
+  else \
+    put_buffer = (put_buffer << size) | code; \
+}
+
+#define PUT_CODE(code, size, diff) { \
+  diff |= code << nbits; \
+  nbits += size; \
+  PUT_BITS(diff, nbits) \
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jcphuff-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jcphuff-neon.c
new file mode 100644
index 0000000..b91c5db
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jcphuff-neon.c
@@ -0,0 +1,622 @@
+/*
+ * jcphuff-neon.c - prepare data for progressive Huffman encoding (Arm Neon)
+ *
+ * Copyright (C) 2020-2021, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "jconfigint.h"
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "neon-compat.h"
+
+#include <arm_neon.h>
+
+
+/* Data preparation for encode_mcu_AC_first().
+ *
+ * The equivalent scalar C function (encode_mcu_AC_first_prepare()) can be
+ * found in jcphuff.c.
+ */
+
+void jsimd_encode_mcu_AC_first_prepare_neon
+  (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
+   JCOEF *values, size_t *zerobits)
+{
+  JCOEF *values_ptr = values;
+  JCOEF *diff_values_ptr = values + DCTSIZE2;
+
+  /* Rows of coefficients to zero (since they haven't been processed) */
+  int i, rows_to_zero = 8;
+
+  for (i = 0; i < Sl / 16; i++) {
+    int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
+    int16x8_t coefs2 = vld1q_dup_s16(block + jpeg_natural_order_start[8]);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[15], coefs2, 7);
+
+    /* Isolate sign of coefficients. */
+    int16x8_t sign_coefs1 = vshrq_n_s16(coefs1, 15);
+    int16x8_t sign_coefs2 = vshrq_n_s16(coefs2, 15);
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs1 = vabsq_s16(coefs1);
+    int16x8_t abs_coefs2 = vabsq_s16(coefs2);
+    coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
+    coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
+
+    /* Compute diff values. */
+    int16x8_t diff1 = veorq_s16(coefs1, sign_coefs1);
+    int16x8_t diff2 = veorq_s16(coefs2, sign_coefs2);
+
+    /* Store transformed coefficients and diff values. */
+    vst1q_s16(values_ptr, coefs1);
+    vst1q_s16(values_ptr + DCTSIZE, coefs2);
+    vst1q_s16(diff_values_ptr, diff1);
+    vst1q_s16(diff_values_ptr + DCTSIZE, diff2);
+    values_ptr += 16;
+    diff_values_ptr += 16;
+    jpeg_natural_order_start += 16;
+    rows_to_zero -= 2;
+  }
+
+  /* Same operation but for remaining partial vector */
+  int remaining_coefs = Sl % 16;
+  if (remaining_coefs > 8) {
+    int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
+    int16x8_t coefs2 = vdupq_n_s16(0);
+    switch (remaining_coefs) {
+    case 15:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[8], coefs2, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+
+    /* Isolate sign of coefficients. */
+    int16x8_t sign_coefs1 = vshrq_n_s16(coefs1, 15);
+    int16x8_t sign_coefs2 = vshrq_n_s16(coefs2, 15);
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs1 = vabsq_s16(coefs1);
+    int16x8_t abs_coefs2 = vabsq_s16(coefs2);
+    coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
+    coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
+
+    /* Compute diff values. */
+    int16x8_t diff1 = veorq_s16(coefs1, sign_coefs1);
+    int16x8_t diff2 = veorq_s16(coefs2, sign_coefs2);
+
+    /* Store transformed coefficients and diff values. */
+    vst1q_s16(values_ptr, coefs1);
+    vst1q_s16(values_ptr + DCTSIZE, coefs2);
+    vst1q_s16(diff_values_ptr, diff1);
+    vst1q_s16(diff_values_ptr + DCTSIZE, diff2);
+    values_ptr += 16;
+    diff_values_ptr += 16;
+    rows_to_zero -= 2;
+
+  } else if (remaining_coefs > 0) {
+    int16x8_t coefs = vdupq_n_s16(0);
+
+    switch (remaining_coefs) {
+    case 8:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs, 7);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 7:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[0], coefs, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+
+    /* Isolate sign of coefficients. */
+    int16x8_t sign_coefs = vshrq_n_s16(coefs, 15);
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs = vabsq_s16(coefs);
+    coefs = vshlq_s16(abs_coefs, vdupq_n_s16(-Al));
+
+    /* Compute diff values. */
+    int16x8_t diff = veorq_s16(coefs, sign_coefs);
+
+    /* Store transformed coefficients and diff values. */
+    vst1q_s16(values_ptr, coefs);
+    vst1q_s16(diff_values_ptr, diff);
+    values_ptr += 8;
+    diff_values_ptr += 8;
+    rows_to_zero--;
+  }
+
+  /* Zero remaining memory in the values and diff_values blocks. */
+  for (i = 0; i < rows_to_zero; i++) {
+    vst1q_s16(values_ptr, vdupq_n_s16(0));
+    vst1q_s16(diff_values_ptr, vdupq_n_s16(0));
+    values_ptr += 8;
+    diff_values_ptr += 8;
+  }
+
+  /* Construct zerobits bitmap.  A set bit means that the corresponding
+   * coefficient != 0.
+   */
+  int16x8_t row0 = vld1q_s16(values + 0 * DCTSIZE);
+  int16x8_t row1 = vld1q_s16(values + 1 * DCTSIZE);
+  int16x8_t row2 = vld1q_s16(values + 2 * DCTSIZE);
+  int16x8_t row3 = vld1q_s16(values + 3 * DCTSIZE);
+  int16x8_t row4 = vld1q_s16(values + 4 * DCTSIZE);
+  int16x8_t row5 = vld1q_s16(values + 5 * DCTSIZE);
+  int16x8_t row6 = vld1q_s16(values + 6 * DCTSIZE);
+  int16x8_t row7 = vld1q_s16(values + 7 * DCTSIZE);
+
+  uint8x8_t row0_eq0 = vmovn_u16(vceqq_s16(row0, vdupq_n_s16(0)));
+  uint8x8_t row1_eq0 = vmovn_u16(vceqq_s16(row1, vdupq_n_s16(0)));
+  uint8x8_t row2_eq0 = vmovn_u16(vceqq_s16(row2, vdupq_n_s16(0)));
+  uint8x8_t row3_eq0 = vmovn_u16(vceqq_s16(row3, vdupq_n_s16(0)));
+  uint8x8_t row4_eq0 = vmovn_u16(vceqq_s16(row4, vdupq_n_s16(0)));
+  uint8x8_t row5_eq0 = vmovn_u16(vceqq_s16(row5, vdupq_n_s16(0)));
+  uint8x8_t row6_eq0 = vmovn_u16(vceqq_s16(row6, vdupq_n_s16(0)));
+  uint8x8_t row7_eq0 = vmovn_u16(vceqq_s16(row7, vdupq_n_s16(0)));
+
+  /* { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } */
+  const uint8x8_t bitmap_mask =
+    vreinterpret_u8_u64(vmov_n_u64(0x8040201008040201));
+
+  row0_eq0 = vand_u8(row0_eq0, bitmap_mask);
+  row1_eq0 = vand_u8(row1_eq0, bitmap_mask);
+  row2_eq0 = vand_u8(row2_eq0, bitmap_mask);
+  row3_eq0 = vand_u8(row3_eq0, bitmap_mask);
+  row4_eq0 = vand_u8(row4_eq0, bitmap_mask);
+  row5_eq0 = vand_u8(row5_eq0, bitmap_mask);
+  row6_eq0 = vand_u8(row6_eq0, bitmap_mask);
+  row7_eq0 = vand_u8(row7_eq0, bitmap_mask);
+
+  uint8x8_t bitmap_rows_01 = vpadd_u8(row0_eq0, row1_eq0);
+  uint8x8_t bitmap_rows_23 = vpadd_u8(row2_eq0, row3_eq0);
+  uint8x8_t bitmap_rows_45 = vpadd_u8(row4_eq0, row5_eq0);
+  uint8x8_t bitmap_rows_67 = vpadd_u8(row6_eq0, row7_eq0);
+  uint8x8_t bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
+  uint8x8_t bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
+  uint8x8_t bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+  /* Move bitmap to a 64-bit scalar register. */
+  uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
+  /* Store zerobits bitmap. */
+  *zerobits = ~bitmap;
+#else
+  /* Move bitmap to two 32-bit scalar registers. */
+  uint32_t bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
+  uint32_t bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
+  /* Store zerobits bitmap. */
+  zerobits[0] = ~bitmap0;
+  zerobits[1] = ~bitmap1;
+#endif
+}
+
+
+/* Data preparation for encode_mcu_AC_refine().
+ *
+ * The equivalent scalar C function (encode_mcu_AC_refine_prepare()) can be
+ * found in jcphuff.c.
+ */
+
+int jsimd_encode_mcu_AC_refine_prepare_neon
+  (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
+   JCOEF *absvalues, size_t *bits)
+{
+  /* Temporary storage buffers for data used to compute the signbits bitmap and
+   * the end-of-block (EOB) position
+   */
+  uint8_t coef_sign_bits[64];
+  uint8_t coef_eq1_bits[64];
+
+  JCOEF *absvalues_ptr = absvalues;
+  uint8_t *coef_sign_bits_ptr = coef_sign_bits;
+  uint8_t *eq1_bits_ptr = coef_eq1_bits;
+
+  /* Rows of coefficients to zero (since they haven't been processed) */
+  int i, rows_to_zero = 8;
+
+  for (i = 0; i < Sl / 16; i++) {
+    int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
+    int16x8_t coefs2 = vld1q_dup_s16(block + jpeg_natural_order_start[8]);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
+    coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[15], coefs2, 7);
+
+    /* Compute and store data for signbits bitmap. */
+    uint8x8_t sign_coefs1 =
+      vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs1, 15)));
+    uint8x8_t sign_coefs2 =
+      vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs2, 15)));
+    vst1_u8(coef_sign_bits_ptr, sign_coefs1);
+    vst1_u8(coef_sign_bits_ptr + DCTSIZE, sign_coefs2);
+
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs1 = vabsq_s16(coefs1);
+    int16x8_t abs_coefs2 = vabsq_s16(coefs2);
+    coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
+    coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
+    vst1q_s16(absvalues_ptr, coefs1);
+    vst1q_s16(absvalues_ptr + DCTSIZE, coefs2);
+
+    /* Test whether transformed coefficient values == 1 (used to find EOB
+     * position.)
+     */
+    uint8x8_t coefs_eq11 = vmovn_u16(vceqq_s16(coefs1, vdupq_n_s16(1)));
+    uint8x8_t coefs_eq12 = vmovn_u16(vceqq_s16(coefs2, vdupq_n_s16(1)));
+    vst1_u8(eq1_bits_ptr, coefs_eq11);
+    vst1_u8(eq1_bits_ptr + DCTSIZE, coefs_eq12);
+
+    absvalues_ptr += 16;
+    coef_sign_bits_ptr += 16;
+    eq1_bits_ptr += 16;
+    jpeg_natural_order_start += 16;
+    rows_to_zero -= 2;
+  }
+
+  /* Same operation but for remaining partial vector */
+  int remaining_coefs = Sl % 16;
+  if (remaining_coefs > 8) {
+    int16x8_t coefs1 = vld1q_dup_s16(block + jpeg_natural_order_start[0]);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs1, 1);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs1, 2);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs1, 3);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs1, 4);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs1, 5);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs1, 6);
+    coefs1 = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs1, 7);
+    int16x8_t coefs2 = vdupq_n_s16(0);
+    switch (remaining_coefs) {
+    case 15:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[14], coefs2, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[13], coefs2, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[12], coefs2, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[11], coefs2, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[10], coefs2, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[9], coefs2, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      coefs2 = vld1q_lane_s16(block + jpeg_natural_order_start[8], coefs2, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+
+    /* Compute and store data for signbits bitmap. */
+    uint8x8_t sign_coefs1 =
+      vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs1, 15)));
+    uint8x8_t sign_coefs2 =
+      vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs2, 15)));
+    vst1_u8(coef_sign_bits_ptr, sign_coefs1);
+    vst1_u8(coef_sign_bits_ptr + DCTSIZE, sign_coefs2);
+
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs1 = vabsq_s16(coefs1);
+    int16x8_t abs_coefs2 = vabsq_s16(coefs2);
+    coefs1 = vshlq_s16(abs_coefs1, vdupq_n_s16(-Al));
+    coefs2 = vshlq_s16(abs_coefs2, vdupq_n_s16(-Al));
+    vst1q_s16(absvalues_ptr, coefs1);
+    vst1q_s16(absvalues_ptr + DCTSIZE, coefs2);
+
+    /* Test whether transformed coefficient values == 1 (used to find EOB
+     * position.)
+     */
+    uint8x8_t coefs_eq11 = vmovn_u16(vceqq_s16(coefs1, vdupq_n_s16(1)));
+    uint8x8_t coefs_eq12 = vmovn_u16(vceqq_s16(coefs2, vdupq_n_s16(1)));
+    vst1_u8(eq1_bits_ptr, coefs_eq11);
+    vst1_u8(eq1_bits_ptr + DCTSIZE, coefs_eq12);
+
+    absvalues_ptr += 16;
+    coef_sign_bits_ptr += 16;
+    eq1_bits_ptr += 16;
+    jpeg_natural_order_start += 16;
+    rows_to_zero -= 2;
+
+  } else if (remaining_coefs > 0) {
+    int16x8_t coefs = vdupq_n_s16(0);
+
+    switch (remaining_coefs) {
+    case 8:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[7], coefs, 7);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 7:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[6], coefs, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[5], coefs, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[4], coefs, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[3], coefs, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[2], coefs, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[1], coefs, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      coefs = vld1q_lane_s16(block + jpeg_natural_order_start[0], coefs, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+
+    /* Compute and store data for signbits bitmap. */
+    uint8x8_t sign_coefs =
+      vmovn_u16(vreinterpretq_u16_s16(vshrq_n_s16(coefs, 15)));
+    vst1_u8(coef_sign_bits_ptr, sign_coefs);
+
+    /* Compute absolute value of coefficients and apply point transform Al. */
+    int16x8_t abs_coefs = vabsq_s16(coefs);
+    coefs = vshlq_s16(abs_coefs, vdupq_n_s16(-Al));
+    vst1q_s16(absvalues_ptr, coefs);
+
+    /* Test whether transformed coefficient values == 1 (used to find EOB
+     * position.)
+     */
+    uint8x8_t coefs_eq1 = vmovn_u16(vceqq_s16(coefs, vdupq_n_s16(1)));
+    vst1_u8(eq1_bits_ptr, coefs_eq1);
+
+    absvalues_ptr += 8;
+    coef_sign_bits_ptr += 8;
+    eq1_bits_ptr += 8;
+    rows_to_zero--;
+  }
+
+  /* Zero remaining memory in blocks. */
+  for (i = 0; i < rows_to_zero; i++) {
+    vst1q_s16(absvalues_ptr, vdupq_n_s16(0));
+    vst1_u8(coef_sign_bits_ptr, vdup_n_u8(0));
+    vst1_u8(eq1_bits_ptr, vdup_n_u8(0));
+    absvalues_ptr += 8;
+    coef_sign_bits_ptr += 8;
+    eq1_bits_ptr += 8;
+  }
+
+  /* Construct zerobits bitmap. */
+  int16x8_t abs_row0 = vld1q_s16(absvalues + 0 * DCTSIZE);
+  int16x8_t abs_row1 = vld1q_s16(absvalues + 1 * DCTSIZE);
+  int16x8_t abs_row2 = vld1q_s16(absvalues + 2 * DCTSIZE);
+  int16x8_t abs_row3 = vld1q_s16(absvalues + 3 * DCTSIZE);
+  int16x8_t abs_row4 = vld1q_s16(absvalues + 4 * DCTSIZE);
+  int16x8_t abs_row5 = vld1q_s16(absvalues + 5 * DCTSIZE);
+  int16x8_t abs_row6 = vld1q_s16(absvalues + 6 * DCTSIZE);
+  int16x8_t abs_row7 = vld1q_s16(absvalues + 7 * DCTSIZE);
+
+  uint8x8_t abs_row0_eq0 = vmovn_u16(vceqq_s16(abs_row0, vdupq_n_s16(0)));
+  uint8x8_t abs_row1_eq0 = vmovn_u16(vceqq_s16(abs_row1, vdupq_n_s16(0)));
+  uint8x8_t abs_row2_eq0 = vmovn_u16(vceqq_s16(abs_row2, vdupq_n_s16(0)));
+  uint8x8_t abs_row3_eq0 = vmovn_u16(vceqq_s16(abs_row3, vdupq_n_s16(0)));
+  uint8x8_t abs_row4_eq0 = vmovn_u16(vceqq_s16(abs_row4, vdupq_n_s16(0)));
+  uint8x8_t abs_row5_eq0 = vmovn_u16(vceqq_s16(abs_row5, vdupq_n_s16(0)));
+  uint8x8_t abs_row6_eq0 = vmovn_u16(vceqq_s16(abs_row6, vdupq_n_s16(0)));
+  uint8x8_t abs_row7_eq0 = vmovn_u16(vceqq_s16(abs_row7, vdupq_n_s16(0)));
+
+  /* { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 } */
+  const uint8x8_t bitmap_mask =
+    vreinterpret_u8_u64(vmov_n_u64(0x8040201008040201));
+
+  abs_row0_eq0 = vand_u8(abs_row0_eq0, bitmap_mask);
+  abs_row1_eq0 = vand_u8(abs_row1_eq0, bitmap_mask);
+  abs_row2_eq0 = vand_u8(abs_row2_eq0, bitmap_mask);
+  abs_row3_eq0 = vand_u8(abs_row3_eq0, bitmap_mask);
+  abs_row4_eq0 = vand_u8(abs_row4_eq0, bitmap_mask);
+  abs_row5_eq0 = vand_u8(abs_row5_eq0, bitmap_mask);
+  abs_row6_eq0 = vand_u8(abs_row6_eq0, bitmap_mask);
+  abs_row7_eq0 = vand_u8(abs_row7_eq0, bitmap_mask);
+
+  uint8x8_t bitmap_rows_01 = vpadd_u8(abs_row0_eq0, abs_row1_eq0);
+  uint8x8_t bitmap_rows_23 = vpadd_u8(abs_row2_eq0, abs_row3_eq0);
+  uint8x8_t bitmap_rows_45 = vpadd_u8(abs_row4_eq0, abs_row5_eq0);
+  uint8x8_t bitmap_rows_67 = vpadd_u8(abs_row6_eq0, abs_row7_eq0);
+  uint8x8_t bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
+  uint8x8_t bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
+  uint8x8_t bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+  /* Move bitmap to a 64-bit scalar register. */
+  uint64_t bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
+  /* Store zerobits bitmap. */
+  bits[0] = ~bitmap;
+#else
+  /* Move bitmap to two 32-bit scalar registers. */
+  uint32_t bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
+  uint32_t bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
+  /* Store zerobits bitmap. */
+  bits[0] = ~bitmap0;
+  bits[1] = ~bitmap1;
+#endif
+
+  /* Construct signbits bitmap. */
+  uint8x8_t signbits_row0 = vld1_u8(coef_sign_bits + 0 * DCTSIZE);
+  uint8x8_t signbits_row1 = vld1_u8(coef_sign_bits + 1 * DCTSIZE);
+  uint8x8_t signbits_row2 = vld1_u8(coef_sign_bits + 2 * DCTSIZE);
+  uint8x8_t signbits_row3 = vld1_u8(coef_sign_bits + 3 * DCTSIZE);
+  uint8x8_t signbits_row4 = vld1_u8(coef_sign_bits + 4 * DCTSIZE);
+  uint8x8_t signbits_row5 = vld1_u8(coef_sign_bits + 5 * DCTSIZE);
+  uint8x8_t signbits_row6 = vld1_u8(coef_sign_bits + 6 * DCTSIZE);
+  uint8x8_t signbits_row7 = vld1_u8(coef_sign_bits + 7 * DCTSIZE);
+
+  signbits_row0 = vand_u8(signbits_row0, bitmap_mask);
+  signbits_row1 = vand_u8(signbits_row1, bitmap_mask);
+  signbits_row2 = vand_u8(signbits_row2, bitmap_mask);
+  signbits_row3 = vand_u8(signbits_row3, bitmap_mask);
+  signbits_row4 = vand_u8(signbits_row4, bitmap_mask);
+  signbits_row5 = vand_u8(signbits_row5, bitmap_mask);
+  signbits_row6 = vand_u8(signbits_row6, bitmap_mask);
+  signbits_row7 = vand_u8(signbits_row7, bitmap_mask);
+
+  bitmap_rows_01 = vpadd_u8(signbits_row0, signbits_row1);
+  bitmap_rows_23 = vpadd_u8(signbits_row2, signbits_row3);
+  bitmap_rows_45 = vpadd_u8(signbits_row4, signbits_row5);
+  bitmap_rows_67 = vpadd_u8(signbits_row6, signbits_row7);
+  bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
+  bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
+  bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+  /* Move bitmap to a 64-bit scalar register. */
+  bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
+  /* Store signbits bitmap. */
+  bits[1] = ~bitmap;
+#else
+  /* Move bitmap to two 32-bit scalar registers. */
+  bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
+  bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
+  /* Store signbits bitmap. */
+  bits[2] = ~bitmap0;
+  bits[3] = ~bitmap1;
+#endif
+
+  /* Construct bitmap to find EOB position (the index of the last coefficient
+   * equal to 1.)
+   */
+  uint8x8_t row0_eq1 = vld1_u8(coef_eq1_bits + 0 * DCTSIZE);
+  uint8x8_t row1_eq1 = vld1_u8(coef_eq1_bits + 1 * DCTSIZE);
+  uint8x8_t row2_eq1 = vld1_u8(coef_eq1_bits + 2 * DCTSIZE);
+  uint8x8_t row3_eq1 = vld1_u8(coef_eq1_bits + 3 * DCTSIZE);
+  uint8x8_t row4_eq1 = vld1_u8(coef_eq1_bits + 4 * DCTSIZE);
+  uint8x8_t row5_eq1 = vld1_u8(coef_eq1_bits + 5 * DCTSIZE);
+  uint8x8_t row6_eq1 = vld1_u8(coef_eq1_bits + 6 * DCTSIZE);
+  uint8x8_t row7_eq1 = vld1_u8(coef_eq1_bits + 7 * DCTSIZE);
+
+  row0_eq1 = vand_u8(row0_eq1, bitmap_mask);
+  row1_eq1 = vand_u8(row1_eq1, bitmap_mask);
+  row2_eq1 = vand_u8(row2_eq1, bitmap_mask);
+  row3_eq1 = vand_u8(row3_eq1, bitmap_mask);
+  row4_eq1 = vand_u8(row4_eq1, bitmap_mask);
+  row5_eq1 = vand_u8(row5_eq1, bitmap_mask);
+  row6_eq1 = vand_u8(row6_eq1, bitmap_mask);
+  row7_eq1 = vand_u8(row7_eq1, bitmap_mask);
+
+  bitmap_rows_01 = vpadd_u8(row0_eq1, row1_eq1);
+  bitmap_rows_23 = vpadd_u8(row2_eq1, row3_eq1);
+  bitmap_rows_45 = vpadd_u8(row4_eq1, row5_eq1);
+  bitmap_rows_67 = vpadd_u8(row6_eq1, row7_eq1);
+  bitmap_rows_0123 = vpadd_u8(bitmap_rows_01, bitmap_rows_23);
+  bitmap_rows_4567 = vpadd_u8(bitmap_rows_45, bitmap_rows_67);
+  bitmap_all = vpadd_u8(bitmap_rows_0123, bitmap_rows_4567);
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+  /* Move bitmap to a 64-bit scalar register. */
+  bitmap = vget_lane_u64(vreinterpret_u64_u8(bitmap_all), 0);
+
+  /* Return EOB position. */
+  if (bitmap == 0) {
+    /* EOB position is defined to be 0 if all coefficients != 1. */
+    return 0;
+  } else {
+    return 63 - BUILTIN_CLZLL(bitmap);
+  }
+#else
+  /* Move bitmap to two 32-bit scalar registers. */
+  bitmap0 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 0);
+  bitmap1 = vget_lane_u32(vreinterpret_u32_u8(bitmap_all), 1);
+
+  /* Return EOB position. */
+  if (bitmap0 == 0 && bitmap1 == 0) {
+    return 0;
+  } else if (bitmap1 != 0) {
+    return 63 - BUILTIN_CLZ(bitmap1);
+  } else {
+    return 31 - BUILTIN_CLZ(bitmap0);
+  }
+#endif
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jcsample-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jcsample-neon.c
new file mode 100644
index 0000000..8a3e237
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jcsample-neon.c
@@ -0,0 +1,192 @@
+/*
+ * jcsample-neon.c - downsampling (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+ALIGN(16) static const uint8_t jsimd_h2_downsample_consts[] = {
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 0 */
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 1 */
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0E,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 2 */
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0D, 0x0D,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 3 */
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 4 */
+  0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 5 */
+  0x08, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 6 */
+  0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 7 */
+  0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,   /* Pad 8 */
+  0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06,   /* Pad 9 */
+  0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05,   /* Pad 10 */
+  0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04,   /* Pad 11 */
+  0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+  0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03,   /* Pad 12 */
+  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+  0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,   /* Pad 13 */
+  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,   /* Pad 14 */
+  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Pad 15 */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+/* Downsample pixel values of a single component.
+ * This version handles the common case of 2:1 horizontal and 1:1 vertical,
+ * without smoothing.
+ */
+
+void jsimd_h2v1_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
+                                JDIMENSION v_samp_factor,
+                                JDIMENSION width_in_blocks,
+                                JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  JSAMPROW inptr, outptr;
+  /* Load expansion mask to pad remaining elements of last DCT block. */
+  const int mask_offset = 16 * ((width_in_blocks * 2 * DCTSIZE) - image_width);
+  const uint8x16_t expand_mask =
+    vld1q_u8(&jsimd_h2_downsample_consts[mask_offset]);
+  /* Load bias pattern (alternating every pixel.) */
+  /* { 0, 1, 0, 1, 0, 1, 0, 1 } */
+  const uint16x8_t bias = vreinterpretq_u16_u32(vdupq_n_u32(0x00010000));
+  unsigned i, outrow;
+
+  for (outrow = 0; outrow < v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr = input_data[outrow];
+
+    /* Downsample all but the last DCT block of pixels. */
+    for (i = 0; i < width_in_blocks - 1; i++) {
+      uint8x16_t pixels = vld1q_u8(inptr + i * 2 * DCTSIZE);
+      /* Add adjacent pixel values, widen to 16-bit, and add bias. */
+      uint16x8_t samples_u16 = vpadalq_u8(bias, pixels);
+      /* Divide total by 2 and narrow to 8-bit. */
+      uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 1);
+      /* Store samples to memory. */
+      vst1_u8(outptr + i * DCTSIZE, samples_u8);
+    }
+
+    /* Load pixels in last DCT block into a table. */
+    uint8x16_t pixels = vld1q_u8(inptr + (width_in_blocks - 1) * 2 * DCTSIZE);
+#if defined(__aarch64__) || defined(_M_ARM64)
+    /* Pad the empty elements with the value of the last pixel. */
+    pixels = vqtbl1q_u8(pixels, expand_mask);
+#else
+    uint8x8x2_t table = { { vget_low_u8(pixels), vget_high_u8(pixels) } };
+    pixels = vcombine_u8(vtbl2_u8(table, vget_low_u8(expand_mask)),
+                         vtbl2_u8(table, vget_high_u8(expand_mask)));
+#endif
+    /* Add adjacent pixel values, widen to 16-bit, and add bias. */
+    uint16x8_t samples_u16 = vpadalq_u8(bias, pixels);
+    /* Divide total by 2, narrow to 8-bit, and store. */
+    uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 1);
+    vst1_u8(outptr + (width_in_blocks - 1) * DCTSIZE, samples_u8);
+  }
+}
+
+
+/* Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * without smoothing.
+ */
+
+void jsimd_h2v2_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
+                                JDIMENSION v_samp_factor,
+                                JDIMENSION width_in_blocks,
+                                JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+  JSAMPROW inptr0, inptr1, outptr;
+  /* Load expansion mask to pad remaining elements of last DCT block. */
+  const int mask_offset = 16 * ((width_in_blocks * 2 * DCTSIZE) - image_width);
+  const uint8x16_t expand_mask =
+    vld1q_u8(&jsimd_h2_downsample_consts[mask_offset]);
+  /* Load bias pattern (alternating every pixel.) */
+  /* { 1, 2, 1, 2, 1, 2, 1, 2 } */
+  const uint16x8_t bias = vreinterpretq_u16_u32(vdupq_n_u32(0x00020001));
+  unsigned i, outrow;
+
+  for (outrow = 0; outrow < v_samp_factor; outrow++) {
+    outptr = output_data[outrow];
+    inptr0 = input_data[outrow];
+    inptr1 = input_data[outrow + 1];
+
+    /* Downsample all but the last DCT block of pixels. */
+    for (i = 0; i < width_in_blocks - 1; i++) {
+      uint8x16_t pixels_r0 = vld1q_u8(inptr0 + i * 2 * DCTSIZE);
+      uint8x16_t pixels_r1 = vld1q_u8(inptr1 + i * 2 * DCTSIZE);
+      /* Add adjacent pixel values in row 0, widen to 16-bit, and add bias. */
+      uint16x8_t samples_u16 = vpadalq_u8(bias, pixels_r0);
+      /* Add adjacent pixel values in row 1, widen to 16-bit, and accumulate.
+       */
+      samples_u16 = vpadalq_u8(samples_u16, pixels_r1);
+      /* Divide total by 4 and narrow to 8-bit. */
+      uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 2);
+      /* Store samples to memory and increment pointers. */
+      vst1_u8(outptr + i * DCTSIZE, samples_u8);
+    }
+
+    /* Load pixels in last DCT block into a table. */
+    uint8x16_t pixels_r0 =
+      vld1q_u8(inptr0 + (width_in_blocks - 1) * 2 * DCTSIZE);
+    uint8x16_t pixels_r1 =
+      vld1q_u8(inptr1 + (width_in_blocks - 1) * 2 * DCTSIZE);
+#if defined(__aarch64__) || defined(_M_ARM64)
+    /* Pad the empty elements with the value of the last pixel. */
+    pixels_r0 = vqtbl1q_u8(pixels_r0, expand_mask);
+    pixels_r1 = vqtbl1q_u8(pixels_r1, expand_mask);
+#else
+    uint8x8x2_t table_r0 =
+      { { vget_low_u8(pixels_r0), vget_high_u8(pixels_r0) } };
+    uint8x8x2_t table_r1 =
+      { { vget_low_u8(pixels_r1), vget_high_u8(pixels_r1) } };
+    pixels_r0 = vcombine_u8(vtbl2_u8(table_r0, vget_low_u8(expand_mask)),
+                            vtbl2_u8(table_r0, vget_high_u8(expand_mask)));
+    pixels_r1 = vcombine_u8(vtbl2_u8(table_r1, vget_low_u8(expand_mask)),
+                            vtbl2_u8(table_r1, vget_high_u8(expand_mask)));
+#endif
+    /* Add adjacent pixel values in row 0, widen to 16-bit, and add bias. */
+    uint16x8_t samples_u16 = vpadalq_u8(bias, pixels_r0);
+    /* Add adjacent pixel values in row 1, widen to 16-bit, and accumulate. */
+    samples_u16 = vpadalq_u8(samples_u16, pixels_r1);
+    /* Divide total by 4, narrow to 8-bit, and store. */
+    uint8x8_t samples_u8 = vshrn_n_u16(samples_u16, 2);
+    vst1_u8(outptr + (width_in_blocks - 1) * DCTSIZE, samples_u8);
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jdcolext-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jdcolext-neon.c
new file mode 100644
index 0000000..c3c07a1
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jdcolext-neon.c
@@ -0,0 +1,374 @@
+/*
+ * jdcolext-neon.c - colorspace conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* This file is included by jdcolor-neon.c. */
+
+
+/* YCbCr -> RGB conversion is defined by the following equations:
+ *    R = Y                        + 1.40200 * (Cr - 128)
+ *    G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
+ *    B = Y + 1.77200 * (Cb - 128)
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.3441467 = 11277 * 2^-15
+ *    0.7141418 = 23401 * 2^-15
+ *    1.4020386 = 22971 * 2^-14
+ *    1.7720337 = 29033 * 2^-14
+ * These constants are defined in jdcolor-neon.c.
+ *
+ * To ensure correct results, rounding is used when descaling.
+ */
+
+/* Notes on safe memory access for YCbCr -> RGB conversion routines:
+ *
+ * Input memory buffers can be safely overread up to the next multiple of
+ * ALIGN_SIZE bytes, since they are always allocated by alloc_sarray() in
+ * jmemmgr.c.
+ *
+ * The output buffer cannot safely be written beyond output_width, since
+ * output_buf points to a possibly unpadded row in the decompressed image
+ * buffer allocated by the calling program.
+ */
+
+void jsimd_ycc_rgb_convert_neon(JDIMENSION output_width, JSAMPIMAGE input_buf,
+                                JDIMENSION input_row, JSAMPARRAY output_buf,
+                                int num_rows)
+{
+  JSAMPROW outptr;
+  /* Pointers to Y, Cb, and Cr data */
+  JSAMPROW inptr0, inptr1, inptr2;
+
+  const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
+  const int16x8_t neg_128 = vdupq_n_s16(-128);
+
+  while (--num_rows >= 0) {
+    inptr0 = input_buf[0][input_row];
+    inptr1 = input_buf[1][input_row];
+    inptr2 = input_buf[2][input_row];
+    input_row++;
+    outptr = *output_buf++;
+    int cols_remaining = output_width;
+    for (; cols_remaining >= 16; cols_remaining -= 16) {
+      uint8x16_t y  = vld1q_u8(inptr0);
+      uint8x16_t cb = vld1q_u8(inptr1);
+      uint8x16_t cr = vld1q_u8(inptr2);
+      /* Subtract 128 from Cb and Cr. */
+      int16x8_t cr_128_l =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
+                                       vget_low_u8(cr)));
+      int16x8_t cr_128_h =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
+                                       vget_high_u8(cr)));
+      int16x8_t cb_128_l =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
+                                       vget_low_u8(cb)));
+      int16x8_t cb_128_h =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128),
+                                       vget_high_u8(cb)));
+      /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+      int32x4_t g_sub_y_ll = vmull_lane_s16(vget_low_s16(cb_128_l), consts, 0);
+      int32x4_t g_sub_y_lh = vmull_lane_s16(vget_high_s16(cb_128_l),
+                                            consts, 0);
+      int32x4_t g_sub_y_hl = vmull_lane_s16(vget_low_s16(cb_128_h), consts, 0);
+      int32x4_t g_sub_y_hh = vmull_lane_s16(vget_high_s16(cb_128_h),
+                                            consts, 0);
+      g_sub_y_ll = vmlsl_lane_s16(g_sub_y_ll, vget_low_s16(cr_128_l),
+                                  consts, 1);
+      g_sub_y_lh = vmlsl_lane_s16(g_sub_y_lh, vget_high_s16(cr_128_l),
+                                  consts, 1);
+      g_sub_y_hl = vmlsl_lane_s16(g_sub_y_hl, vget_low_s16(cr_128_h),
+                                  consts, 1);
+      g_sub_y_hh = vmlsl_lane_s16(g_sub_y_hh, vget_high_s16(cr_128_h),
+                                  consts, 1);
+      /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+      int16x8_t g_sub_y_l = vcombine_s16(vrshrn_n_s32(g_sub_y_ll, 15),
+                                         vrshrn_n_s32(g_sub_y_lh, 15));
+      int16x8_t g_sub_y_h = vcombine_s16(vrshrn_n_s32(g_sub_y_hl, 15),
+                                         vrshrn_n_s32(g_sub_y_hh, 15));
+      /* Compute R-Y: 1.40200 * (Cr - 128) */
+      int16x8_t r_sub_y_l = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128_l, 1),
+                                               consts, 2);
+      int16x8_t r_sub_y_h = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128_h, 1),
+                                               consts, 2);
+      /* Compute B-Y: 1.77200 * (Cb - 128) */
+      int16x8_t b_sub_y_l = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128_l, 1),
+                                               consts, 3);
+      int16x8_t b_sub_y_h = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128_h, 1),
+                                               consts, 3);
+      /* Add Y. */
+      int16x8_t r_l =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y_l),
+                                       vget_low_u8(y)));
+      int16x8_t r_h =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y_h),
+                                       vget_high_u8(y)));
+      int16x8_t b_l =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y_l),
+                                       vget_low_u8(y)));
+      int16x8_t b_h =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y_h),
+                                       vget_high_u8(y)));
+      int16x8_t g_l =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y_l),
+                                       vget_low_u8(y)));
+      int16x8_t g_h =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y_h),
+                                       vget_high_u8(y)));
+
+#if RGB_PIXELSIZE == 4
+      uint8x16x4_t rgba;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgba.val[RGB_RED] = vcombine_u8(vqmovun_s16(r_l), vqmovun_s16(r_h));
+      rgba.val[RGB_GREEN] = vcombine_u8(vqmovun_s16(g_l), vqmovun_s16(g_h));
+      rgba.val[RGB_BLUE] = vcombine_u8(vqmovun_s16(b_l), vqmovun_s16(b_h));
+      /* Set alpha channel to opaque (0xFF). */
+      rgba.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
+      /* Store RGBA pixel data to memory. */
+      vst4q_u8(outptr, rgba);
+#elif RGB_PIXELSIZE == 3
+      uint8x16x3_t rgb;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgb.val[RGB_RED] = vcombine_u8(vqmovun_s16(r_l), vqmovun_s16(r_h));
+      rgb.val[RGB_GREEN] = vcombine_u8(vqmovun_s16(g_l), vqmovun_s16(g_h));
+      rgb.val[RGB_BLUE] = vcombine_u8(vqmovun_s16(b_l), vqmovun_s16(b_h));
+      /* Store RGB pixel data to memory. */
+      vst3q_u8(outptr, rgb);
+#else
+      /* Pack R, G, and B values in ratio 5:6:5. */
+      uint16x8_t rgb565_l = vqshluq_n_s16(r_l, 8);
+      rgb565_l = vsriq_n_u16(rgb565_l, vqshluq_n_s16(g_l, 8), 5);
+      rgb565_l = vsriq_n_u16(rgb565_l, vqshluq_n_s16(b_l, 8), 11);
+      uint16x8_t rgb565_h = vqshluq_n_s16(r_h, 8);
+      rgb565_h = vsriq_n_u16(rgb565_h, vqshluq_n_s16(g_h, 8), 5);
+      rgb565_h = vsriq_n_u16(rgb565_h, vqshluq_n_s16(b_h, 8), 11);
+      /* Store RGB pixel data to memory. */
+      vst1q_u16((uint16_t *)outptr, rgb565_l);
+      vst1q_u16(((uint16_t *)outptr) + 8, rgb565_h);
+#endif
+
+      /* Increment pointers. */
+      inptr0 += 16;
+      inptr1 += 16;
+      inptr2 += 16;
+      outptr += (RGB_PIXELSIZE * 16);
+    }
+
+    if (cols_remaining >= 8) {
+      uint8x8_t y  = vld1_u8(inptr0);
+      uint8x8_t cb = vld1_u8(inptr1);
+      uint8x8_t cr = vld1_u8(inptr2);
+      /* Subtract 128 from Cb and Cr. */
+      int16x8_t cr_128 =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+      int16x8_t cb_128 =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+      /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+      int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+      int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+      g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+      g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+      /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+      int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                       vrshrn_n_s32(g_sub_y_h, 15));
+      /* Compute R-Y: 1.40200 * (Cr - 128) */
+      int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1),
+                                             consts, 2);
+      /* Compute B-Y: 1.77200 * (Cb - 128) */
+      int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1),
+                                             consts, 3);
+      /* Add Y. */
+      int16x8_t r =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y), y));
+      int16x8_t b =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y), y));
+      int16x8_t g =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y), y));
+
+#if RGB_PIXELSIZE == 4
+      uint8x8x4_t rgba;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgba.val[RGB_RED] = vqmovun_s16(r);
+      rgba.val[RGB_GREEN] = vqmovun_s16(g);
+      rgba.val[RGB_BLUE] = vqmovun_s16(b);
+      /* Set alpha channel to opaque (0xFF). */
+      rgba.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+      /* Store RGBA pixel data to memory. */
+      vst4_u8(outptr, rgba);
+#elif RGB_PIXELSIZE == 3
+      uint8x8x3_t rgb;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgb.val[RGB_RED] = vqmovun_s16(r);
+      rgb.val[RGB_GREEN] = vqmovun_s16(g);
+      rgb.val[RGB_BLUE] = vqmovun_s16(b);
+      /* Store RGB pixel data to memory. */
+      vst3_u8(outptr, rgb);
+#else
+      /* Pack R, G, and B values in ratio 5:6:5. */
+      uint16x8_t rgb565 = vqshluq_n_s16(r, 8);
+      rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(g, 8), 5);
+      rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(b, 8), 11);
+      /* Store RGB pixel data to memory. */
+      vst1q_u16((uint16_t *)outptr, rgb565);
+#endif
+
+      /* Increment pointers. */
+      inptr0 += 8;
+      inptr1 += 8;
+      inptr2 += 8;
+      outptr += (RGB_PIXELSIZE * 8);
+      cols_remaining -= 8;
+    }
+
+    /* Handle the tail elements. */
+    if (cols_remaining > 0) {
+      uint8x8_t y  = vld1_u8(inptr0);
+      uint8x8_t cb = vld1_u8(inptr1);
+      uint8x8_t cr = vld1_u8(inptr2);
+      /* Subtract 128 from Cb and Cr. */
+      int16x8_t cr_128 =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+      int16x8_t cb_128 =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+      /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+      int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+      int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+      g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+      g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+      /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+      int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                       vrshrn_n_s32(g_sub_y_h, 15));
+      /* Compute R-Y: 1.40200 * (Cr - 128) */
+      int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1),
+                                             consts, 2);
+      /* Compute B-Y: 1.77200 * (Cb - 128) */
+      int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1),
+                                             consts, 3);
+      /* Add Y. */
+      int16x8_t r =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y), y));
+      int16x8_t b =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y), y));
+      int16x8_t g =
+        vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y), y));
+
+#if RGB_PIXELSIZE == 4
+      uint8x8x4_t rgba;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgba.val[RGB_RED] = vqmovun_s16(r);
+      rgba.val[RGB_GREEN] = vqmovun_s16(g);
+      rgba.val[RGB_BLUE] = vqmovun_s16(b);
+      /* Set alpha channel to opaque (0xFF). */
+      rgba.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+      /* Store RGBA pixel data to memory. */
+      switch (cols_remaining) {
+      case 7:
+        vst4_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgba, 6);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 6:
+        vst4_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgba, 5);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 5:
+        vst4_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgba, 4);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 4:
+        vst4_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgba, 3);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 3:
+        vst4_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgba, 2);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 2:
+        vst4_lane_u8(outptr + RGB_PIXELSIZE, rgba, 1);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 1:
+        vst4_lane_u8(outptr, rgba, 0);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      default:
+        break;
+      }
+#elif RGB_PIXELSIZE == 3
+      uint8x8x3_t rgb;
+      /* Convert each component to unsigned and narrow, clamping to [0-255]. */
+      rgb.val[RGB_RED] = vqmovun_s16(r);
+      rgb.val[RGB_GREEN] = vqmovun_s16(g);
+      rgb.val[RGB_BLUE] = vqmovun_s16(b);
+      /* Store RGB pixel data to memory. */
+      switch (cols_remaining) {
+      case 7:
+        vst3_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgb, 6);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 6:
+        vst3_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgb, 5);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 5:
+        vst3_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgb, 4);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 4:
+        vst3_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgb, 3);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 3:
+        vst3_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgb, 2);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 2:
+        vst3_lane_u8(outptr + RGB_PIXELSIZE, rgb, 1);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 1:
+        vst3_lane_u8(outptr, rgb, 0);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      default:
+        break;
+      }
+#else
+      /* Pack R, G, and B values in ratio 5:6:5. */
+      uint16x8_t rgb565 = vqshluq_n_s16(r, 8);
+      rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(g, 8), 5);
+      rgb565 = vsriq_n_u16(rgb565, vqshluq_n_s16(b, 8), 11);
+      /* Store RGB565 pixel data to memory. */
+      switch (cols_remaining) {
+      case 7:
+        vst1q_lane_u16((uint16_t *)(outptr + 6 * RGB_PIXELSIZE), rgb565, 6);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 6:
+        vst1q_lane_u16((uint16_t *)(outptr + 5 * RGB_PIXELSIZE), rgb565, 5);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 5:
+        vst1q_lane_u16((uint16_t *)(outptr + 4 * RGB_PIXELSIZE), rgb565, 4);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 4:
+        vst1q_lane_u16((uint16_t *)(outptr + 3 * RGB_PIXELSIZE), rgb565, 3);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 3:
+        vst1q_lane_u16((uint16_t *)(outptr + 2 * RGB_PIXELSIZE), rgb565, 2);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 2:
+        vst1q_lane_u16((uint16_t *)(outptr + RGB_PIXELSIZE), rgb565, 1);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      case 1:
+        vst1q_lane_u16((uint16_t *)outptr, rgb565, 0);
+        FALLTHROUGH             /*FALLTHROUGH*/
+      default:
+        break;
+      }
+#endif
+    }
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jdcolor-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jdcolor-neon.c
new file mode 100644
index 0000000..ea4668f
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jdcolor-neon.c
@@ -0,0 +1,142 @@
+/*
+ * jdcolor-neon.c - colorspace conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "jconfigint.h"
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+/* YCbCr -> RGB conversion constants */
+
+#define F_0_344  11277  /* 0.3441467 = 11277 * 2^-15 */
+#define F_0_714  23401  /* 0.7141418 = 23401 * 2^-15 */
+#define F_1_402  22971  /* 1.4020386 = 22971 * 2^-14 */
+#define F_1_772  29033  /* 1.7720337 = 29033 * 2^-14 */
+
+ALIGN(16) static const int16_t jsimd_ycc_rgb_convert_neon_consts[] = {
+  -F_0_344, F_0_714, F_1_402, F_1_772
+};
+
+
+/* Include inline routines for colorspace extensions. */
+
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED  EXT_RGB_RED
+#define RGB_GREEN  EXT_RGB_GREEN
+#define RGB_BLUE  EXT_RGB_BLUE
+#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extrgb_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+#define RGB_RED  EXT_RGBX_RED
+#define RGB_GREEN  EXT_RGBX_GREEN
+#define RGB_BLUE  EXT_RGBX_BLUE
+#define RGB_ALPHA  3
+#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extrgbx_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+#define RGB_RED  EXT_BGR_RED
+#define RGB_GREEN  EXT_BGR_GREEN
+#define RGB_BLUE  EXT_BGR_BLUE
+#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extbgr_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+#define RGB_RED  EXT_BGRX_RED
+#define RGB_GREEN  EXT_BGRX_GREEN
+#define RGB_BLUE  EXT_BGRX_BLUE
+#define RGB_ALPHA  3
+#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extbgrx_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+#define RGB_RED  EXT_XBGR_RED
+#define RGB_GREEN  EXT_XBGR_GREEN
+#define RGB_BLUE  EXT_XBGR_BLUE
+#define RGB_ALPHA  0
+#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extxbgr_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+#define RGB_RED  EXT_XRGB_RED
+#define RGB_GREEN  EXT_XRGB_GREEN
+#define RGB_BLUE  EXT_XRGB_BLUE
+#define RGB_ALPHA  0
+#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_extxrgb_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
+
+/* YCbCr -> RGB565 Conversion */
+
+#define RGB_PIXELSIZE  2
+#define jsimd_ycc_rgb_convert_neon  jsimd_ycc_rgb565_convert_neon
+#include "jdcolext-neon.c"
+#undef RGB_PIXELSIZE
+#undef jsimd_ycc_rgb_convert_neon
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jdmerge-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jdmerge-neon.c
new file mode 100644
index 0000000..e4f91fd
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jdmerge-neon.c
@@ -0,0 +1,145 @@
+/*
+ * jdmerge-neon.c - merged upsampling/color conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "jconfigint.h"
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+/* YCbCr -> RGB conversion constants */
+
+#define F_0_344  11277  /* 0.3441467 = 11277 * 2^-15 */
+#define F_0_714  23401  /* 0.7141418 = 23401 * 2^-15 */
+#define F_1_402  22971  /* 1.4020386 = 22971 * 2^-14 */
+#define F_1_772  29033  /* 1.7720337 = 29033 * 2^-14 */
+
+ALIGN(16) static const int16_t jsimd_ycc_rgb_convert_neon_consts[] = {
+  -F_0_344, F_0_714, F_1_402, F_1_772
+};
+
+
+/* Include inline routines for colorspace extensions. */
+
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+
+#define RGB_RED  EXT_RGB_RED
+#define RGB_GREEN  EXT_RGB_GREEN
+#define RGB_BLUE  EXT_RGB_BLUE
+#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extrgb_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extrgb_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
+#undef jsimd_h2v2_merged_upsample_neon
+
+#define RGB_RED  EXT_RGBX_RED
+#define RGB_GREEN  EXT_RGBX_GREEN
+#define RGB_BLUE  EXT_RGBX_BLUE
+#define RGB_ALPHA  3
+#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extrgbx_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extrgbx_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
+#undef jsimd_h2v2_merged_upsample_neon
+
+#define RGB_RED  EXT_BGR_RED
+#define RGB_GREEN  EXT_BGR_GREEN
+#define RGB_BLUE  EXT_BGR_BLUE
+#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extbgr_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extbgr_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
+#undef jsimd_h2v2_merged_upsample_neon
+
+#define RGB_RED  EXT_BGRX_RED
+#define RGB_GREEN  EXT_BGRX_GREEN
+#define RGB_BLUE  EXT_BGRX_BLUE
+#define RGB_ALPHA  3
+#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extbgrx_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extbgrx_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
+#undef jsimd_h2v2_merged_upsample_neon
+
+#define RGB_RED  EXT_XBGR_RED
+#define RGB_GREEN  EXT_XBGR_GREEN
+#define RGB_BLUE  EXT_XBGR_BLUE
+#define RGB_ALPHA  0
+#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extxbgr_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extxbgr_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
+#undef jsimd_h2v2_merged_upsample_neon
+
+#define RGB_RED  EXT_XRGB_RED
+#define RGB_GREEN  EXT_XRGB_GREEN
+#define RGB_BLUE  EXT_XRGB_BLUE
+#define RGB_ALPHA  0
+#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
+#define jsimd_h2v1_merged_upsample_neon  jsimd_h2v1_extxrgb_merged_upsample_neon
+#define jsimd_h2v2_merged_upsample_neon  jsimd_h2v2_extxrgb_merged_upsample_neon
+#include "jdmrgext-neon.c"
+#undef RGB_RED
+#undef RGB_GREEN
+#undef RGB_BLUE
+#undef RGB_ALPHA
+#undef RGB_PIXELSIZE
+#undef jsimd_h2v1_merged_upsample_neon
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jdmrgext-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jdmrgext-neon.c
new file mode 100644
index 0000000..5b89bdb
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jdmrgext-neon.c
@@ -0,0 +1,723 @@
+/*
+ * jdmrgext-neon.c - merged upsampling/color conversion (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/* This file is included by jdmerge-neon.c. */
+
+
+/* These routines combine simple (non-fancy, i.e. non-smooth) h2v1 or h2v2
+ * chroma upsampling and YCbCr -> RGB color conversion into a single function.
+ *
+ * As with the standalone functions, YCbCr -> RGB conversion is defined by the
+ * following equations:
+ *    R = Y                        + 1.40200 * (Cr - 128)
+ *    G = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)
+ *    B = Y + 1.77200 * (Cb - 128)
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.3441467 = 11277 * 2^-15
+ *    0.7141418 = 23401 * 2^-15
+ *    1.4020386 = 22971 * 2^-14
+ *    1.7720337 = 29033 * 2^-14
+ * These constants are defined in jdmerge-neon.c.
+ *
+ * To ensure correct results, rounding is used when descaling.
+ */
+
+/* Notes on safe memory access for merged upsampling/YCbCr -> RGB conversion
+ * routines:
+ *
+ * Input memory buffers can be safely overread up to the next multiple of
+ * ALIGN_SIZE bytes, since they are always allocated by alloc_sarray() in
+ * jmemmgr.c.
+ *
+ * The output buffer cannot safely be written beyond output_width, since
+ * output_buf points to a possibly unpadded row in the decompressed image
+ * buffer allocated by the calling program.
+ */
+
+/* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
+ */
+
+void jsimd_h2v1_merged_upsample_neon(JDIMENSION output_width,
+                                     JSAMPIMAGE input_buf,
+                                     JDIMENSION in_row_group_ctr,
+                                     JSAMPARRAY output_buf)
+{
+  JSAMPROW outptr;
+  /* Pointers to Y, Cb, and Cr data */
+  JSAMPROW inptr0, inptr1, inptr2;
+
+  const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
+  const int16x8_t neg_128 = vdupq_n_s16(-128);
+
+  inptr0 = input_buf[0][in_row_group_ctr];
+  inptr1 = input_buf[1][in_row_group_ctr];
+  inptr2 = input_buf[2][in_row_group_ctr];
+  outptr = output_buf[0];
+
+  int cols_remaining = output_width;
+  for (; cols_remaining >= 16; cols_remaining -= 16) {
+    /* De-interleave Y component values into two separate vectors, one
+     * containing the component values with even-numbered indices and one
+     * containing the component values with odd-numbered indices.
+     */
+    uint8x8x2_t y = vld2_u8(inptr0);
+    uint8x8_t cb = vld1_u8(inptr1);
+    uint8x8_t cr = vld1_u8(inptr2);
+    /* Subtract 128 from Cb and Cr. */
+    int16x8_t cr_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+    int16x8_t cb_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+    /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+    int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+    int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+    g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+    g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+    /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+    int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                     vrshrn_n_s32(g_sub_y_h, 15));
+    /* Compute R-Y: 1.40200 * (Cr - 128) */
+    int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
+    /* Compute B-Y: 1.77200 * (Cb - 128) */
+    int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
+    /* Add the chroma-derived values (G-Y, R-Y, and B-Y) to both the "even" and
+     * "odd" Y component values.  This effectively upsamples the chroma
+     * components horizontally.
+     */
+    int16x8_t g_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y.val[0]));
+    int16x8_t r_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y.val[0]));
+    int16x8_t b_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y.val[0]));
+    int16x8_t g_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y.val[1]));
+    int16x8_t r_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y.val[1]));
+    int16x8_t b_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y.val[1]));
+    /* Convert each component to unsigned and narrow, clamping to [0-255].
+     * Re-interleave the "even" and "odd" component values.
+     */
+    uint8x8x2_t r = vzip_u8(vqmovun_s16(r_even), vqmovun_s16(r_odd));
+    uint8x8x2_t g = vzip_u8(vqmovun_s16(g_even), vqmovun_s16(g_odd));
+    uint8x8x2_t b = vzip_u8(vqmovun_s16(b_even), vqmovun_s16(b_odd));
+
+#ifdef RGB_ALPHA
+    uint8x16x4_t rgba;
+    rgba.val[RGB_RED] = vcombine_u8(r.val[0], r.val[1]);
+    rgba.val[RGB_GREEN] = vcombine_u8(g.val[0], g.val[1]);
+    rgba.val[RGB_BLUE] = vcombine_u8(b.val[0], b.val[1]);
+    /* Set alpha channel to opaque (0xFF). */
+    rgba.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
+    /* Store RGBA pixel data to memory. */
+    vst4q_u8(outptr, rgba);
+#else
+    uint8x16x3_t rgb;
+    rgb.val[RGB_RED] = vcombine_u8(r.val[0], r.val[1]);
+    rgb.val[RGB_GREEN] = vcombine_u8(g.val[0], g.val[1]);
+    rgb.val[RGB_BLUE] = vcombine_u8(b.val[0], b.val[1]);
+    /* Store RGB pixel data to memory. */
+    vst3q_u8(outptr, rgb);
+#endif
+
+    /* Increment pointers. */
+    inptr0 += 16;
+    inptr1 += 8;
+    inptr2 += 8;
+    outptr += (RGB_PIXELSIZE * 16);
+  }
+
+  if (cols_remaining > 0) {
+    /* De-interleave Y component values into two separate vectors, one
+     * containing the component values with even-numbered indices and one
+     * containing the component values with odd-numbered indices.
+     */
+    uint8x8x2_t y = vld2_u8(inptr0);
+    uint8x8_t cb = vld1_u8(inptr1);
+    uint8x8_t cr = vld1_u8(inptr2);
+    /* Subtract 128 from Cb and Cr. */
+    int16x8_t cr_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+    int16x8_t cb_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+    /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+    int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+    int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+    g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+    g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+    /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+    int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                     vrshrn_n_s32(g_sub_y_h, 15));
+    /* Compute R-Y: 1.40200 * (Cr - 128) */
+    int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
+    /* Compute B-Y: 1.77200 * (Cb - 128) */
+    int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
+    /* Add the chroma-derived values (G-Y, R-Y, and B-Y) to both the "even" and
+     * "odd" Y component values.  This effectively upsamples the chroma
+     * components horizontally.
+     */
+    int16x8_t g_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y.val[0]));
+    int16x8_t r_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y.val[0]));
+    int16x8_t b_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y.val[0]));
+    int16x8_t g_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y.val[1]));
+    int16x8_t r_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y.val[1]));
+    int16x8_t b_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y.val[1]));
+    /* Convert each component to unsigned and narrow, clamping to [0-255].
+     * Re-interleave the "even" and "odd" component values.
+     */
+    uint8x8x2_t r = vzip_u8(vqmovun_s16(r_even), vqmovun_s16(r_odd));
+    uint8x8x2_t g = vzip_u8(vqmovun_s16(g_even), vqmovun_s16(g_odd));
+    uint8x8x2_t b = vzip_u8(vqmovun_s16(b_even), vqmovun_s16(b_odd));
+
+#ifdef RGB_ALPHA
+    uint8x8x4_t rgba_h;
+    rgba_h.val[RGB_RED] = r.val[1];
+    rgba_h.val[RGB_GREEN] = g.val[1];
+    rgba_h.val[RGB_BLUE] = b.val[1];
+    /* Set alpha channel to opaque (0xFF). */
+    rgba_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+    uint8x8x4_t rgba_l;
+    rgba_l.val[RGB_RED] = r.val[0];
+    rgba_l.val[RGB_GREEN] = g.val[0];
+    rgba_l.val[RGB_BLUE] = b.val[0];
+    /* Set alpha channel to opaque (0xFF). */
+    rgba_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+    /* Store RGBA pixel data to memory. */
+    switch (cols_remaining) {
+    case 15:
+      vst4_lane_u8(outptr + 14 * RGB_PIXELSIZE, rgba_h, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      vst4_lane_u8(outptr + 13 * RGB_PIXELSIZE, rgba_h, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      vst4_lane_u8(outptr + 12 * RGB_PIXELSIZE, rgba_h, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      vst4_lane_u8(outptr + 11 * RGB_PIXELSIZE, rgba_h, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      vst4_lane_u8(outptr + 10 * RGB_PIXELSIZE, rgba_h, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      vst4_lane_u8(outptr + 9 * RGB_PIXELSIZE, rgba_h, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      vst4_lane_u8(outptr + 8 * RGB_PIXELSIZE, rgba_h, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 8:
+      vst4_u8(outptr, rgba_l);
+      break;
+    case 7:
+      vst4_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgba_l, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      vst4_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgba_l, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      vst4_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgba_l, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      vst4_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgba_l, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      vst4_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgba_l, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      vst4_lane_u8(outptr + RGB_PIXELSIZE, rgba_l, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      vst4_lane_u8(outptr, rgba_l, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+#else
+    uint8x8x3_t rgb_h;
+    rgb_h.val[RGB_RED] = r.val[1];
+    rgb_h.val[RGB_GREEN] = g.val[1];
+    rgb_h.val[RGB_BLUE] = b.val[1];
+    uint8x8x3_t rgb_l;
+    rgb_l.val[RGB_RED] = r.val[0];
+    rgb_l.val[RGB_GREEN] = g.val[0];
+    rgb_l.val[RGB_BLUE] = b.val[0];
+    /* Store RGB pixel data to memory. */
+    switch (cols_remaining) {
+    case 15:
+      vst3_lane_u8(outptr + 14 * RGB_PIXELSIZE, rgb_h, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      vst3_lane_u8(outptr + 13 * RGB_PIXELSIZE, rgb_h, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      vst3_lane_u8(outptr + 12 * RGB_PIXELSIZE, rgb_h, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      vst3_lane_u8(outptr + 11 * RGB_PIXELSIZE, rgb_h, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      vst3_lane_u8(outptr + 10 * RGB_PIXELSIZE, rgb_h, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      vst3_lane_u8(outptr + 9 * RGB_PIXELSIZE, rgb_h, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      vst3_lane_u8(outptr + 8 * RGB_PIXELSIZE, rgb_h, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 8:
+      vst3_u8(outptr, rgb_l);
+      break;
+    case 7:
+      vst3_lane_u8(outptr + 6 * RGB_PIXELSIZE, rgb_l, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      vst3_lane_u8(outptr + 5 * RGB_PIXELSIZE, rgb_l, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      vst3_lane_u8(outptr + 4 * RGB_PIXELSIZE, rgb_l, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      vst3_lane_u8(outptr + 3 * RGB_PIXELSIZE, rgb_l, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      vst3_lane_u8(outptr + 2 * RGB_PIXELSIZE, rgb_l, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      vst3_lane_u8(outptr + RGB_PIXELSIZE, rgb_l, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      vst3_lane_u8(outptr, rgb_l, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+#endif
+  }
+}
+
+
+/* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
+ *
+ * See comments above for details regarding color conversion and safe memory
+ * access.
+ */
+
+void jsimd_h2v2_merged_upsample_neon(JDIMENSION output_width,
+                                     JSAMPIMAGE input_buf,
+                                     JDIMENSION in_row_group_ctr,
+                                     JSAMPARRAY output_buf)
+{
+  JSAMPROW outptr0, outptr1;
+  /* Pointers to Y (both rows), Cb, and Cr data */
+  JSAMPROW inptr0_0, inptr0_1, inptr1, inptr2;
+
+  const int16x4_t consts = vld1_s16(jsimd_ycc_rgb_convert_neon_consts);
+  const int16x8_t neg_128 = vdupq_n_s16(-128);
+
+  inptr0_0 = input_buf[0][in_row_group_ctr * 2];
+  inptr0_1 = input_buf[0][in_row_group_ctr * 2 + 1];
+  inptr1 = input_buf[1][in_row_group_ctr];
+  inptr2 = input_buf[2][in_row_group_ctr];
+  outptr0 = output_buf[0];
+  outptr1 = output_buf[1];
+
+  int cols_remaining = output_width;
+  for (; cols_remaining >= 16; cols_remaining -= 16) {
+    /* For each row, de-interleave Y component values into two separate
+     * vectors, one containing the component values with even-numbered indices
+     * and one containing the component values with odd-numbered indices.
+     */
+    uint8x8x2_t y0 = vld2_u8(inptr0_0);
+    uint8x8x2_t y1 = vld2_u8(inptr0_1);
+    uint8x8_t cb = vld1_u8(inptr1);
+    uint8x8_t cr = vld1_u8(inptr2);
+    /* Subtract 128 from Cb and Cr. */
+    int16x8_t cr_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+    int16x8_t cb_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+    /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+    int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+    int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+    g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+    g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+    /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+    int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                     vrshrn_n_s32(g_sub_y_h, 15));
+    /* Compute R-Y: 1.40200 * (Cr - 128) */
+    int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
+    /* Compute B-Y: 1.77200 * (Cb - 128) */
+    int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
+    /* For each row, add the chroma-derived values (G-Y, R-Y, and B-Y) to both
+     * the "even" and "odd" Y component values.  This effectively upsamples the
+     * chroma components both horizontally and vertically.
+     */
+    int16x8_t g0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y0.val[0]));
+    int16x8_t r0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y0.val[0]));
+    int16x8_t b0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y0.val[0]));
+    int16x8_t g0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y0.val[1]));
+    int16x8_t r0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y0.val[1]));
+    int16x8_t b0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y0.val[1]));
+    int16x8_t g1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y1.val[0]));
+    int16x8_t r1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y1.val[0]));
+    int16x8_t b1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y1.val[0]));
+    int16x8_t g1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y1.val[1]));
+    int16x8_t r1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y1.val[1]));
+    int16x8_t b1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y1.val[1]));
+    /* Convert each component to unsigned and narrow, clamping to [0-255].
+     * Re-interleave the "even" and "odd" component values.
+     */
+    uint8x8x2_t r0 = vzip_u8(vqmovun_s16(r0_even), vqmovun_s16(r0_odd));
+    uint8x8x2_t r1 = vzip_u8(vqmovun_s16(r1_even), vqmovun_s16(r1_odd));
+    uint8x8x2_t g0 = vzip_u8(vqmovun_s16(g0_even), vqmovun_s16(g0_odd));
+    uint8x8x2_t g1 = vzip_u8(vqmovun_s16(g1_even), vqmovun_s16(g1_odd));
+    uint8x8x2_t b0 = vzip_u8(vqmovun_s16(b0_even), vqmovun_s16(b0_odd));
+    uint8x8x2_t b1 = vzip_u8(vqmovun_s16(b1_even), vqmovun_s16(b1_odd));
+
+#ifdef RGB_ALPHA
+    uint8x16x4_t rgba0, rgba1;
+    rgba0.val[RGB_RED] = vcombine_u8(r0.val[0], r0.val[1]);
+    rgba1.val[RGB_RED] = vcombine_u8(r1.val[0], r1.val[1]);
+    rgba0.val[RGB_GREEN] = vcombine_u8(g0.val[0], g0.val[1]);
+    rgba1.val[RGB_GREEN] = vcombine_u8(g1.val[0], g1.val[1]);
+    rgba0.val[RGB_BLUE] = vcombine_u8(b0.val[0], b0.val[1]);
+    rgba1.val[RGB_BLUE] = vcombine_u8(b1.val[0], b1.val[1]);
+    /* Set alpha channel to opaque (0xFF). */
+    rgba0.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
+    rgba1.val[RGB_ALPHA] = vdupq_n_u8(0xFF);
+    /* Store RGBA pixel data to memory. */
+    vst4q_u8(outptr0, rgba0);
+    vst4q_u8(outptr1, rgba1);
+#else
+    uint8x16x3_t rgb0, rgb1;
+    rgb0.val[RGB_RED] = vcombine_u8(r0.val[0], r0.val[1]);
+    rgb1.val[RGB_RED] = vcombine_u8(r1.val[0], r1.val[1]);
+    rgb0.val[RGB_GREEN] = vcombine_u8(g0.val[0], g0.val[1]);
+    rgb1.val[RGB_GREEN] = vcombine_u8(g1.val[0], g1.val[1]);
+    rgb0.val[RGB_BLUE] = vcombine_u8(b0.val[0], b0.val[1]);
+    rgb1.val[RGB_BLUE] = vcombine_u8(b1.val[0], b1.val[1]);
+    /* Store RGB pixel data to memory. */
+    vst3q_u8(outptr0, rgb0);
+    vst3q_u8(outptr1, rgb1);
+#endif
+
+    /* Increment pointers. */
+    inptr0_0 += 16;
+    inptr0_1 += 16;
+    inptr1 += 8;
+    inptr2 += 8;
+    outptr0 += (RGB_PIXELSIZE * 16);
+    outptr1 += (RGB_PIXELSIZE * 16);
+  }
+
+  if (cols_remaining > 0) {
+    /* For each row, de-interleave Y component values into two separate
+     * vectors, one containing the component values with even-numbered indices
+     * and one containing the component values with odd-numbered indices.
+     */
+    uint8x8x2_t y0 = vld2_u8(inptr0_0);
+    uint8x8x2_t y1 = vld2_u8(inptr0_1);
+    uint8x8_t cb = vld1_u8(inptr1);
+    uint8x8_t cr = vld1_u8(inptr2);
+    /* Subtract 128 from Cb and Cr. */
+    int16x8_t cr_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cr));
+    int16x8_t cb_128 =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(neg_128), cb));
+    /* Compute G-Y: - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128) */
+    int32x4_t g_sub_y_l = vmull_lane_s16(vget_low_s16(cb_128), consts, 0);
+    int32x4_t g_sub_y_h = vmull_lane_s16(vget_high_s16(cb_128), consts, 0);
+    g_sub_y_l = vmlsl_lane_s16(g_sub_y_l, vget_low_s16(cr_128), consts, 1);
+    g_sub_y_h = vmlsl_lane_s16(g_sub_y_h, vget_high_s16(cr_128), consts, 1);
+    /* Descale G components: shift right 15, round, and narrow to 16-bit. */
+    int16x8_t g_sub_y = vcombine_s16(vrshrn_n_s32(g_sub_y_l, 15),
+                                     vrshrn_n_s32(g_sub_y_h, 15));
+    /* Compute R-Y: 1.40200 * (Cr - 128) */
+    int16x8_t r_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cr_128, 1), consts, 2);
+    /* Compute B-Y: 1.77200 * (Cb - 128) */
+    int16x8_t b_sub_y = vqrdmulhq_lane_s16(vshlq_n_s16(cb_128, 1), consts, 3);
+    /* For each row, add the chroma-derived values (G-Y, R-Y, and B-Y) to both
+     * the "even" and "odd" Y component values.  This effectively upsamples the
+     * chroma components both horizontally and vertically.
+     */
+    int16x8_t g0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y0.val[0]));
+    int16x8_t r0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y0.val[0]));
+    int16x8_t b0_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y0.val[0]));
+    int16x8_t g0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y0.val[1]));
+    int16x8_t r0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y0.val[1]));
+    int16x8_t b0_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y0.val[1]));
+    int16x8_t g1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y1.val[0]));
+    int16x8_t r1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y1.val[0]));
+    int16x8_t b1_even =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y1.val[0]));
+    int16x8_t g1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(g_sub_y),
+                                     y1.val[1]));
+    int16x8_t r1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(r_sub_y),
+                                     y1.val[1]));
+    int16x8_t b1_odd =
+      vreinterpretq_s16_u16(vaddw_u8(vreinterpretq_u16_s16(b_sub_y),
+                                     y1.val[1]));
+    /* Convert each component to unsigned and narrow, clamping to [0-255].
+     * Re-interleave the "even" and "odd" component values.
+     */
+    uint8x8x2_t r0 = vzip_u8(vqmovun_s16(r0_even), vqmovun_s16(r0_odd));
+    uint8x8x2_t r1 = vzip_u8(vqmovun_s16(r1_even), vqmovun_s16(r1_odd));
+    uint8x8x2_t g0 = vzip_u8(vqmovun_s16(g0_even), vqmovun_s16(g0_odd));
+    uint8x8x2_t g1 = vzip_u8(vqmovun_s16(g1_even), vqmovun_s16(g1_odd));
+    uint8x8x2_t b0 = vzip_u8(vqmovun_s16(b0_even), vqmovun_s16(b0_odd));
+    uint8x8x2_t b1 = vzip_u8(vqmovun_s16(b1_even), vqmovun_s16(b1_odd));
+
+#ifdef RGB_ALPHA
+    uint8x8x4_t rgba0_h, rgba1_h;
+    rgba0_h.val[RGB_RED] = r0.val[1];
+    rgba1_h.val[RGB_RED] = r1.val[1];
+    rgba0_h.val[RGB_GREEN] = g0.val[1];
+    rgba1_h.val[RGB_GREEN] = g1.val[1];
+    rgba0_h.val[RGB_BLUE] = b0.val[1];
+    rgba1_h.val[RGB_BLUE] = b1.val[1];
+    /* Set alpha channel to opaque (0xFF). */
+    rgba0_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+    rgba1_h.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+
+    uint8x8x4_t rgba0_l, rgba1_l;
+    rgba0_l.val[RGB_RED] = r0.val[0];
+    rgba1_l.val[RGB_RED] = r1.val[0];
+    rgba0_l.val[RGB_GREEN] = g0.val[0];
+    rgba1_l.val[RGB_GREEN] = g1.val[0];
+    rgba0_l.val[RGB_BLUE] = b0.val[0];
+    rgba1_l.val[RGB_BLUE] = b1.val[0];
+    /* Set alpha channel to opaque (0xFF). */
+    rgba0_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+    rgba1_l.val[RGB_ALPHA] = vdup_n_u8(0xFF);
+    /* Store RGBA pixel data to memory. */
+    switch (cols_remaining) {
+    case 15:
+      vst4_lane_u8(outptr0 + 14 * RGB_PIXELSIZE, rgba0_h, 6);
+      vst4_lane_u8(outptr1 + 14 * RGB_PIXELSIZE, rgba1_h, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      vst4_lane_u8(outptr0 + 13 * RGB_PIXELSIZE, rgba0_h, 5);
+      vst4_lane_u8(outptr1 + 13 * RGB_PIXELSIZE, rgba1_h, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      vst4_lane_u8(outptr0 + 12 * RGB_PIXELSIZE, rgba0_h, 4);
+      vst4_lane_u8(outptr1 + 12 * RGB_PIXELSIZE, rgba1_h, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      vst4_lane_u8(outptr0 + 11 * RGB_PIXELSIZE, rgba0_h, 3);
+      vst4_lane_u8(outptr1 + 11 * RGB_PIXELSIZE, rgba1_h, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      vst4_lane_u8(outptr0 + 10 * RGB_PIXELSIZE, rgba0_h, 2);
+      vst4_lane_u8(outptr1 + 10 * RGB_PIXELSIZE, rgba1_h, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      vst4_lane_u8(outptr0 + 9 * RGB_PIXELSIZE, rgba0_h, 1);
+      vst4_lane_u8(outptr1 + 9 * RGB_PIXELSIZE, rgba1_h, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      vst4_lane_u8(outptr0 + 8 * RGB_PIXELSIZE, rgba0_h, 0);
+      vst4_lane_u8(outptr1 + 8 * RGB_PIXELSIZE, rgba1_h, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 8:
+      vst4_u8(outptr0, rgba0_l);
+      vst4_u8(outptr1, rgba1_l);
+      break;
+    case 7:
+      vst4_lane_u8(outptr0 + 6 * RGB_PIXELSIZE, rgba0_l, 6);
+      vst4_lane_u8(outptr1 + 6 * RGB_PIXELSIZE, rgba1_l, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      vst4_lane_u8(outptr0 + 5 * RGB_PIXELSIZE, rgba0_l, 5);
+      vst4_lane_u8(outptr1 + 5 * RGB_PIXELSIZE, rgba1_l, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      vst4_lane_u8(outptr0 + 4 * RGB_PIXELSIZE, rgba0_l, 4);
+      vst4_lane_u8(outptr1 + 4 * RGB_PIXELSIZE, rgba1_l, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      vst4_lane_u8(outptr0 + 3 * RGB_PIXELSIZE, rgba0_l, 3);
+      vst4_lane_u8(outptr1 + 3 * RGB_PIXELSIZE, rgba1_l, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      vst4_lane_u8(outptr0 + 2 * RGB_PIXELSIZE, rgba0_l, 2);
+      vst4_lane_u8(outptr1 + 2 * RGB_PIXELSIZE, rgba1_l, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      vst4_lane_u8(outptr0 + 1 * RGB_PIXELSIZE, rgba0_l, 1);
+      vst4_lane_u8(outptr1 + 1 * RGB_PIXELSIZE, rgba1_l, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      vst4_lane_u8(outptr0, rgba0_l, 0);
+      vst4_lane_u8(outptr1, rgba1_l, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+#else
+    uint8x8x3_t rgb0_h, rgb1_h;
+    rgb0_h.val[RGB_RED] = r0.val[1];
+    rgb1_h.val[RGB_RED] = r1.val[1];
+    rgb0_h.val[RGB_GREEN] = g0.val[1];
+    rgb1_h.val[RGB_GREEN] = g1.val[1];
+    rgb0_h.val[RGB_BLUE] = b0.val[1];
+    rgb1_h.val[RGB_BLUE] = b1.val[1];
+
+    uint8x8x3_t rgb0_l, rgb1_l;
+    rgb0_l.val[RGB_RED] = r0.val[0];
+    rgb1_l.val[RGB_RED] = r1.val[0];
+    rgb0_l.val[RGB_GREEN] = g0.val[0];
+    rgb1_l.val[RGB_GREEN] = g1.val[0];
+    rgb0_l.val[RGB_BLUE] = b0.val[0];
+    rgb1_l.val[RGB_BLUE] = b1.val[0];
+    /* Store RGB pixel data to memory. */
+    switch (cols_remaining) {
+    case 15:
+      vst3_lane_u8(outptr0 + 14 * RGB_PIXELSIZE, rgb0_h, 6);
+      vst3_lane_u8(outptr1 + 14 * RGB_PIXELSIZE, rgb1_h, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 14:
+      vst3_lane_u8(outptr0 + 13 * RGB_PIXELSIZE, rgb0_h, 5);
+      vst3_lane_u8(outptr1 + 13 * RGB_PIXELSIZE, rgb1_h, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 13:
+      vst3_lane_u8(outptr0 + 12 * RGB_PIXELSIZE, rgb0_h, 4);
+      vst3_lane_u8(outptr1 + 12 * RGB_PIXELSIZE, rgb1_h, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 12:
+      vst3_lane_u8(outptr0 + 11 * RGB_PIXELSIZE, rgb0_h, 3);
+      vst3_lane_u8(outptr1 + 11 * RGB_PIXELSIZE, rgb1_h, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 11:
+      vst3_lane_u8(outptr0 + 10 * RGB_PIXELSIZE, rgb0_h, 2);
+      vst3_lane_u8(outptr1 + 10 * RGB_PIXELSIZE, rgb1_h, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 10:
+      vst3_lane_u8(outptr0 + 9 * RGB_PIXELSIZE, rgb0_h, 1);
+      vst3_lane_u8(outptr1 + 9 * RGB_PIXELSIZE, rgb1_h, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 9:
+      vst3_lane_u8(outptr0 + 8 * RGB_PIXELSIZE, rgb0_h, 0);
+      vst3_lane_u8(outptr1 + 8 * RGB_PIXELSIZE, rgb1_h, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 8:
+      vst3_u8(outptr0, rgb0_l);
+      vst3_u8(outptr1, rgb1_l);
+      break;
+    case 7:
+      vst3_lane_u8(outptr0 + 6 * RGB_PIXELSIZE, rgb0_l, 6);
+      vst3_lane_u8(outptr1 + 6 * RGB_PIXELSIZE, rgb1_l, 6);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 6:
+      vst3_lane_u8(outptr0 + 5 * RGB_PIXELSIZE, rgb0_l, 5);
+      vst3_lane_u8(outptr1 + 5 * RGB_PIXELSIZE, rgb1_l, 5);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 5:
+      vst3_lane_u8(outptr0 + 4 * RGB_PIXELSIZE, rgb0_l, 4);
+      vst3_lane_u8(outptr1 + 4 * RGB_PIXELSIZE, rgb1_l, 4);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 4:
+      vst3_lane_u8(outptr0 + 3 * RGB_PIXELSIZE, rgb0_l, 3);
+      vst3_lane_u8(outptr1 + 3 * RGB_PIXELSIZE, rgb1_l, 3);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 3:
+      vst3_lane_u8(outptr0 + 2 * RGB_PIXELSIZE, rgb0_l, 2);
+      vst3_lane_u8(outptr1 + 2 * RGB_PIXELSIZE, rgb1_l, 2);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 2:
+      vst3_lane_u8(outptr0 + 1 * RGB_PIXELSIZE, rgb0_l, 1);
+      vst3_lane_u8(outptr1 + 1 * RGB_PIXELSIZE, rgb1_l, 1);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    case 1:
+      vst3_lane_u8(outptr0, rgb0_l, 0);
+      vst3_lane_u8(outptr1, rgb1_l, 0);
+      FALLTHROUGH               /*FALLTHROUGH*/
+    default:
+      break;
+    }
+#endif
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jdsample-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jdsample-neon.c
new file mode 100644
index 0000000..90ec678
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jdsample-neon.c
@@ -0,0 +1,569 @@
+/*
+ * jdsample-neon.c - upsampling (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+
+#include <arm_neon.h>
+
+
+/* The diagram below shows a row of samples produced by h2v1 downsampling.
+ *
+ *                s0        s1        s2
+ *            +---------+---------+---------+
+ *            |         |         |         |
+ *            | p0   p1 | p2   p3 | p4   p5 |
+ *            |         |         |         |
+ *            +---------+---------+---------+
+ *
+ * Samples s0-s2 were created by averaging the original pixel component values
+ * centered at positions p0-p5 above.  To approximate those original pixel
+ * component values, we proportionally blend the adjacent samples in each row.
+ *
+ * An upsampled pixel component value is computed by blending the sample
+ * containing the pixel center with the nearest neighboring sample, in the
+ * ratio 3:1.  For example:
+ *     p1(upsampled) = 3/4 * s0 + 1/4 * s1
+ *     p2(upsampled) = 3/4 * s1 + 1/4 * s0
+ * When computing the first and last pixel component values in the row, there
+ * is no adjacent sample to blend, so:
+ *     p0(upsampled) = s0
+ *     p5(upsampled) = s2
+ */
+
+void jsimd_h2v1_fancy_upsample_neon(int max_v_samp_factor,
+                                    JDIMENSION downsampled_width,
+                                    JSAMPARRAY input_data,
+                                    JSAMPARRAY *output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  JSAMPROW inptr, outptr;
+  int inrow;
+  unsigned colctr;
+  /* Set up constants. */
+  const uint16x8_t one_u16 = vdupq_n_u16(1);
+  const uint8x8_t three_u8 = vdup_n_u8(3);
+
+  for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
+    inptr = input_data[inrow];
+    outptr = output_data[inrow];
+    /* First pixel component value in this row of the original image */
+    *outptr = (JSAMPLE)GETJSAMPLE(*inptr);
+
+    /*    3/4 * containing sample + 1/4 * nearest neighboring sample
+     * For p1: containing sample = s0, nearest neighboring sample = s1
+     * For p2: containing sample = s1, nearest neighboring sample = s0
+     */
+    uint8x16_t s0 = vld1q_u8(inptr);
+    uint8x16_t s1 = vld1q_u8(inptr + 1);
+    /* Multiplication makes vectors twice as wide.  '_l' and '_h' suffixes
+     * denote low half and high half respectively.
+     */
+    uint16x8_t s1_add_3s0_l =
+      vmlal_u8(vmovl_u8(vget_low_u8(s1)), vget_low_u8(s0), three_u8);
+    uint16x8_t s1_add_3s0_h =
+      vmlal_u8(vmovl_u8(vget_high_u8(s1)), vget_high_u8(s0), three_u8);
+    uint16x8_t s0_add_3s1_l =
+      vmlal_u8(vmovl_u8(vget_low_u8(s0)), vget_low_u8(s1), three_u8);
+    uint16x8_t s0_add_3s1_h =
+      vmlal_u8(vmovl_u8(vget_high_u8(s0)), vget_high_u8(s1), three_u8);
+    /* Add ordered dithering bias to odd pixel values. */
+    s0_add_3s1_l = vaddq_u16(s0_add_3s1_l, one_u16);
+    s0_add_3s1_h = vaddq_u16(s0_add_3s1_h, one_u16);
+
+    /* The offset is initially 1, because the first pixel component has already
+     * been stored.  However, in subsequent iterations of the SIMD loop, this
+     * offset is (2 * colctr - 1) to stay within the bounds of the sample
+     * buffers without having to resort to a slow scalar tail case for the last
+     * (downsampled_width % 16) samples.  See "Creation of 2-D sample arrays"
+     * in jmemmgr.c for more details.
+     */
+    unsigned outptr_offset = 1;
+    uint8x16x2_t output_pixels;
+
+    /* We use software pipelining to maximise performance.  The code indented
+     * an extra two spaces begins the next iteration of the loop.
+     */
+    for (colctr = 16; colctr < downsampled_width; colctr += 16) {
+
+        s0 = vld1q_u8(inptr + colctr - 1);
+        s1 = vld1q_u8(inptr + colctr);
+
+      /* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
+      output_pixels.val[0] = vcombine_u8(vrshrn_n_u16(s1_add_3s0_l, 2),
+                                         vrshrn_n_u16(s1_add_3s0_h, 2));
+      output_pixels.val[1] = vcombine_u8(vshrn_n_u16(s0_add_3s1_l, 2),
+                                         vshrn_n_u16(s0_add_3s1_h, 2));
+
+        /* Multiplication makes vectors twice as wide.  '_l' and '_h' suffixes
+         * denote low half and high half respectively.
+         */
+        s1_add_3s0_l =
+          vmlal_u8(vmovl_u8(vget_low_u8(s1)), vget_low_u8(s0), three_u8);
+        s1_add_3s0_h =
+          vmlal_u8(vmovl_u8(vget_high_u8(s1)), vget_high_u8(s0), three_u8);
+        s0_add_3s1_l =
+          vmlal_u8(vmovl_u8(vget_low_u8(s0)), vget_low_u8(s1), three_u8);
+        s0_add_3s1_h =
+          vmlal_u8(vmovl_u8(vget_high_u8(s0)), vget_high_u8(s1), three_u8);
+        /* Add ordered dithering bias to odd pixel values. */
+        s0_add_3s1_l = vaddq_u16(s0_add_3s1_l, one_u16);
+        s0_add_3s1_h = vaddq_u16(s0_add_3s1_h, one_u16);
+
+      /* Store pixel component values to memory. */
+      vst2q_u8(outptr + outptr_offset, output_pixels);
+      outptr_offset = 2 * colctr - 1;
+    }
+
+    /* Complete the last iteration of the loop. */
+
+    /* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
+    output_pixels.val[0] = vcombine_u8(vrshrn_n_u16(s1_add_3s0_l, 2),
+                                       vrshrn_n_u16(s1_add_3s0_h, 2));
+    output_pixels.val[1] = vcombine_u8(vshrn_n_u16(s0_add_3s1_l, 2),
+                                       vshrn_n_u16(s0_add_3s1_h, 2));
+    /* Store pixel component values to memory. */
+    vst2q_u8(outptr + outptr_offset, output_pixels);
+
+    /* Last pixel component value in this row of the original image */
+    outptr[2 * downsampled_width - 1] =
+      GETJSAMPLE(inptr[downsampled_width - 1]);
+  }
+}
+
+
+/* The diagram below shows an array of samples produced by h2v2 downsampling.
+ *
+ *                s0        s1        s2
+ *            +---------+---------+---------+
+ *            | p0   p1 | p2   p3 | p4   p5 |
+ *       sA   |         |         |         |
+ *            | p6   p7 | p8   p9 | p10  p11|
+ *            +---------+---------+---------+
+ *            | p12  p13| p14  p15| p16  p17|
+ *       sB   |         |         |         |
+ *            | p18  p19| p20  p21| p22  p23|
+ *            +---------+---------+---------+
+ *            | p24  p25| p26  p27| p28  p29|
+ *       sC   |         |         |         |
+ *            | p30  p31| p32  p33| p34  p35|
+ *            +---------+---------+---------+
+ *
+ * Samples s0A-s2C were created by averaging the original pixel component
+ * values centered at positions p0-p35 above.  To approximate one of those
+ * original pixel component values, we proportionally blend the sample
+ * containing the pixel center with the nearest neighboring samples in each
+ * row, column, and diagonal.
+ *
+ * An upsampled pixel component value is computed by first blending the sample
+ * containing the pixel center with the nearest neighboring samples in the
+ * same column, in the ratio 3:1, and then blending each column sum with the
+ * nearest neighboring column sum, in the ratio 3:1.  For example:
+ *     p14(upsampled) = 3/4 * (3/4 * s1B + 1/4 * s1A) +
+ *                      1/4 * (3/4 * s0B + 1/4 * s0A)
+ *                    = 9/16 * s1B + 3/16 * s1A + 3/16 * s0B + 1/16 * s0A
+ * When computing the first and last pixel component values in the row, there
+ * is no horizontally adjacent sample to blend, so:
+ *     p12(upsampled) = 3/4 * s0B + 1/4 * s0A
+ *     p23(upsampled) = 3/4 * s2B + 1/4 * s2C
+ * When computing the first and last pixel component values in the column,
+ * there is no vertically adjacent sample to blend, so:
+ *     p2(upsampled) = 3/4 * s1A + 1/4 * s0A
+ *     p33(upsampled) = 3/4 * s1C + 1/4 * s2C
+ * When computing the corner pixel component values, there is no adjacent
+ * sample to blend, so:
+ *     p0(upsampled) = s0A
+ *     p35(upsampled) = s2C
+ */
+
+void jsimd_h2v2_fancy_upsample_neon(int max_v_samp_factor,
+                                    JDIMENSION downsampled_width,
+                                    JSAMPARRAY input_data,
+                                    JSAMPARRAY *output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  JSAMPROW inptr0, inptr1, inptr2, outptr0, outptr1;
+  int inrow, outrow;
+  unsigned colctr;
+  /* Set up constants. */
+  const uint16x8_t seven_u16 = vdupq_n_u16(7);
+  const uint8x8_t three_u8 = vdup_n_u8(3);
+  const uint16x8_t three_u16 = vdupq_n_u16(3);
+
+  inrow = outrow = 0;
+  while (outrow < max_v_samp_factor) {
+    inptr0 = input_data[inrow - 1];
+    inptr1 = input_data[inrow];
+    inptr2 = input_data[inrow + 1];
+    /* Suffixes 0 and 1 denote the upper and lower rows of output pixels,
+     * respectively.
+     */
+    outptr0 = output_data[outrow++];
+    outptr1 = output_data[outrow++];
+
+    /* First pixel component value in this row of the original image */
+    int s0colsum0 = GETJSAMPLE(*inptr1) * 3 + GETJSAMPLE(*inptr0);
+    *outptr0 = (JSAMPLE)((s0colsum0 * 4 + 8) >> 4);
+    int s0colsum1 = GETJSAMPLE(*inptr1) * 3 + GETJSAMPLE(*inptr2);
+    *outptr1 = (JSAMPLE)((s0colsum1 * 4 + 8) >> 4);
+
+    /* Step 1: Blend samples vertically in columns s0 and s1.
+     * Leave the divide by 4 until the end, when it can be done for both
+     * dimensions at once, right-shifting by 4.
+     */
+
+    /* Load and compute s0colsum0 and s0colsum1. */
+    uint8x16_t s0A = vld1q_u8(inptr0);
+    uint8x16_t s0B = vld1q_u8(inptr1);
+    uint8x16_t s0C = vld1q_u8(inptr2);
+    /* Multiplication makes vectors twice as wide.  '_l' and '_h' suffixes
+     * denote low half and high half respectively.
+     */
+    uint16x8_t s0colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s0A)),
+                                      vget_low_u8(s0B), three_u8);
+    uint16x8_t s0colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s0A)),
+                                      vget_high_u8(s0B), three_u8);
+    uint16x8_t s0colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s0C)),
+                                      vget_low_u8(s0B), three_u8);
+    uint16x8_t s0colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s0C)),
+                                      vget_high_u8(s0B), three_u8);
+    /* Load and compute s1colsum0 and s1colsum1. */
+    uint8x16_t s1A = vld1q_u8(inptr0 + 1);
+    uint8x16_t s1B = vld1q_u8(inptr1 + 1);
+    uint8x16_t s1C = vld1q_u8(inptr2 + 1);
+    uint16x8_t s1colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s1A)),
+                                      vget_low_u8(s1B), three_u8);
+    uint16x8_t s1colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s1A)),
+                                      vget_high_u8(s1B), three_u8);
+    uint16x8_t s1colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s1C)),
+                                      vget_low_u8(s1B), three_u8);
+    uint16x8_t s1colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s1C)),
+                                      vget_high_u8(s1B), three_u8);
+
+    /* Step 2: Blend the already-blended columns. */
+
+    uint16x8_t output0_p1_l = vmlaq_u16(s1colsum0_l, s0colsum0_l, three_u16);
+    uint16x8_t output0_p1_h = vmlaq_u16(s1colsum0_h, s0colsum0_h, three_u16);
+    uint16x8_t output0_p2_l = vmlaq_u16(s0colsum0_l, s1colsum0_l, three_u16);
+    uint16x8_t output0_p2_h = vmlaq_u16(s0colsum0_h, s1colsum0_h, three_u16);
+    uint16x8_t output1_p1_l = vmlaq_u16(s1colsum1_l, s0colsum1_l, three_u16);
+    uint16x8_t output1_p1_h = vmlaq_u16(s1colsum1_h, s0colsum1_h, three_u16);
+    uint16x8_t output1_p2_l = vmlaq_u16(s0colsum1_l, s1colsum1_l, three_u16);
+    uint16x8_t output1_p2_h = vmlaq_u16(s0colsum1_h, s1colsum1_h, three_u16);
+    /* Add ordered dithering bias to odd pixel values. */
+    output0_p1_l = vaddq_u16(output0_p1_l, seven_u16);
+    output0_p1_h = vaddq_u16(output0_p1_h, seven_u16);
+    output1_p1_l = vaddq_u16(output1_p1_l, seven_u16);
+    output1_p1_h = vaddq_u16(output1_p1_h, seven_u16);
+    /* Right-shift by 4 (divide by 16), narrow to 8-bit, and combine. */
+    uint8x16x2_t output_pixels0 = { {
+      vcombine_u8(vshrn_n_u16(output0_p1_l, 4), vshrn_n_u16(output0_p1_h, 4)),
+      vcombine_u8(vrshrn_n_u16(output0_p2_l, 4), vrshrn_n_u16(output0_p2_h, 4))
+    } };
+    uint8x16x2_t output_pixels1 = { {
+      vcombine_u8(vshrn_n_u16(output1_p1_l, 4), vshrn_n_u16(output1_p1_h, 4)),
+      vcombine_u8(vrshrn_n_u16(output1_p2_l, 4), vrshrn_n_u16(output1_p2_h, 4))
+    } };
+
+    /* Store pixel component values to memory.
+     * The minimum size of the output buffer for each row is 64 bytes => no
+     * need to worry about buffer overflow here.  See "Creation of 2-D sample
+     * arrays" in jmemmgr.c for more details.
+     */
+    vst2q_u8(outptr0 + 1, output_pixels0);
+    vst2q_u8(outptr1 + 1, output_pixels1);
+
+    /* The first pixel of the image shifted our loads and stores by one byte.
+     * We have to re-align on a 32-byte boundary at some point before the end
+     * of the row (we do it now on the 32/33 pixel boundary) to stay within the
+     * bounds of the sample buffers without having to resort to a slow scalar
+     * tail case for the last (downsampled_width % 16) samples.  See "Creation
+     * of 2-D sample arrays" in jmemmgr.c for more details.
+     */
+    for (colctr = 16; colctr < downsampled_width; colctr += 16) {
+      /* Step 1: Blend samples vertically in columns s0 and s1. */
+
+      /* Load and compute s0colsum0 and s0colsum1. */
+      s0A = vld1q_u8(inptr0 + colctr - 1);
+      s0B = vld1q_u8(inptr1 + colctr - 1);
+      s0C = vld1q_u8(inptr2 + colctr - 1);
+      s0colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s0A)), vget_low_u8(s0B),
+                             three_u8);
+      s0colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s0A)), vget_high_u8(s0B),
+                             three_u8);
+      s0colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s0C)), vget_low_u8(s0B),
+                             three_u8);
+      s0colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s0C)), vget_high_u8(s0B),
+                             three_u8);
+      /* Load and compute s1colsum0 and s1colsum1. */
+      s1A = vld1q_u8(inptr0 + colctr);
+      s1B = vld1q_u8(inptr1 + colctr);
+      s1C = vld1q_u8(inptr2 + colctr);
+      s1colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(s1A)), vget_low_u8(s1B),
+                             three_u8);
+      s1colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(s1A)), vget_high_u8(s1B),
+                             three_u8);
+      s1colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(s1C)), vget_low_u8(s1B),
+                             three_u8);
+      s1colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(s1C)), vget_high_u8(s1B),
+                             three_u8);
+
+      /* Step 2: Blend the already-blended columns. */
+
+      output0_p1_l = vmlaq_u16(s1colsum0_l, s0colsum0_l, three_u16);
+      output0_p1_h = vmlaq_u16(s1colsum0_h, s0colsum0_h, three_u16);
+      output0_p2_l = vmlaq_u16(s0colsum0_l, s1colsum0_l, three_u16);
+      output0_p2_h = vmlaq_u16(s0colsum0_h, s1colsum0_h, three_u16);
+      output1_p1_l = vmlaq_u16(s1colsum1_l, s0colsum1_l, three_u16);
+      output1_p1_h = vmlaq_u16(s1colsum1_h, s0colsum1_h, three_u16);
+      output1_p2_l = vmlaq_u16(s0colsum1_l, s1colsum1_l, three_u16);
+      output1_p2_h = vmlaq_u16(s0colsum1_h, s1colsum1_h, three_u16);
+      /* Add ordered dithering bias to odd pixel values. */
+      output0_p1_l = vaddq_u16(output0_p1_l, seven_u16);
+      output0_p1_h = vaddq_u16(output0_p1_h, seven_u16);
+      output1_p1_l = vaddq_u16(output1_p1_l, seven_u16);
+      output1_p1_h = vaddq_u16(output1_p1_h, seven_u16);
+      /* Right-shift by 4 (divide by 16), narrow to 8-bit, and combine. */
+      output_pixels0.val[0] = vcombine_u8(vshrn_n_u16(output0_p1_l, 4),
+                                          vshrn_n_u16(output0_p1_h, 4));
+      output_pixels0.val[1] = vcombine_u8(vrshrn_n_u16(output0_p2_l, 4),
+                                          vrshrn_n_u16(output0_p2_h, 4));
+      output_pixels1.val[0] = vcombine_u8(vshrn_n_u16(output1_p1_l, 4),
+                                          vshrn_n_u16(output1_p1_h, 4));
+      output_pixels1.val[1] = vcombine_u8(vrshrn_n_u16(output1_p2_l, 4),
+                                          vrshrn_n_u16(output1_p2_h, 4));
+      /* Store pixel component values to memory. */
+      vst2q_u8(outptr0 + 2 * colctr - 1, output_pixels0);
+      vst2q_u8(outptr1 + 2 * colctr - 1, output_pixels1);
+    }
+
+    /* Last pixel component value in this row of the original image */
+    int s1colsum0 = GETJSAMPLE(inptr1[downsampled_width - 1]) * 3 +
+                    GETJSAMPLE(inptr0[downsampled_width - 1]);
+    outptr0[2 * downsampled_width - 1] = (JSAMPLE)((s1colsum0 * 4 + 7) >> 4);
+    int s1colsum1 = GETJSAMPLE(inptr1[downsampled_width - 1]) * 3 +
+                    GETJSAMPLE(inptr2[downsampled_width - 1]);
+    outptr1[2 * downsampled_width - 1] = (JSAMPLE)((s1colsum1 * 4 + 7) >> 4);
+    inrow++;
+  }
+}
+
+
+/* The diagram below shows a column of samples produced by h1v2 downsampling
+ * (or by losslessly rotating or transposing an h2v1-downsampled image.)
+ *
+ *            +---------+
+ *            |   p0    |
+ *     sA     |         |
+ *            |   p1    |
+ *            +---------+
+ *            |   p2    |
+ *     sB     |         |
+ *            |   p3    |
+ *            +---------+
+ *            |   p4    |
+ *     sC     |         |
+ *            |   p5    |
+ *            +---------+
+ *
+ * Samples sA-sC were created by averaging the original pixel component values
+ * centered at positions p0-p5 above.  To approximate those original pixel
+ * component values, we proportionally blend the adjacent samples in each
+ * column.
+ *
+ * An upsampled pixel component value is computed by blending the sample
+ * containing the pixel center with the nearest neighboring sample, in the
+ * ratio 3:1.  For example:
+ *     p1(upsampled) = 3/4 * sA + 1/4 * sB
+ *     p2(upsampled) = 3/4 * sB + 1/4 * sA
+ * When computing the first and last pixel component values in the column,
+ * there is no adjacent sample to blend, so:
+ *     p0(upsampled) = sA
+ *     p5(upsampled) = sC
+ */
+
+void jsimd_h1v2_fancy_upsample_neon(int max_v_samp_factor,
+                                    JDIMENSION downsampled_width,
+                                    JSAMPARRAY input_data,
+                                    JSAMPARRAY *output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  JSAMPROW inptr0, inptr1, inptr2, outptr0, outptr1;
+  int inrow, outrow;
+  unsigned colctr;
+  /* Set up constants. */
+  const uint16x8_t one_u16 = vdupq_n_u16(1);
+  const uint8x8_t three_u8 = vdup_n_u8(3);
+
+  inrow = outrow = 0;
+  while (outrow < max_v_samp_factor) {
+    inptr0 = input_data[inrow - 1];
+    inptr1 = input_data[inrow];
+    inptr2 = input_data[inrow + 1];
+    /* Suffixes 0 and 1 denote the upper and lower rows of output pixels,
+     * respectively.
+     */
+    outptr0 = output_data[outrow++];
+    outptr1 = output_data[outrow++];
+    inrow++;
+
+    /* The size of the input and output buffers is always a multiple of 32
+     * bytes => no need to worry about buffer overflow when reading/writing
+     * memory.  See "Creation of 2-D sample arrays" in jmemmgr.c for more
+     * details.
+     */
+    for (colctr = 0; colctr < downsampled_width; colctr += 16) {
+      /* Load samples. */
+      uint8x16_t sA = vld1q_u8(inptr0 + colctr);
+      uint8x16_t sB = vld1q_u8(inptr1 + colctr);
+      uint8x16_t sC = vld1q_u8(inptr2 + colctr);
+      /* Blend samples vertically. */
+      uint16x8_t colsum0_l = vmlal_u8(vmovl_u8(vget_low_u8(sA)),
+                                      vget_low_u8(sB), three_u8);
+      uint16x8_t colsum0_h = vmlal_u8(vmovl_u8(vget_high_u8(sA)),
+                                      vget_high_u8(sB), three_u8);
+      uint16x8_t colsum1_l = vmlal_u8(vmovl_u8(vget_low_u8(sC)),
+                                      vget_low_u8(sB), three_u8);
+      uint16x8_t colsum1_h = vmlal_u8(vmovl_u8(vget_high_u8(sC)),
+                                      vget_high_u8(sB), three_u8);
+      /* Add ordered dithering bias to pixel values in even output rows. */
+      colsum0_l = vaddq_u16(colsum0_l, one_u16);
+      colsum0_h = vaddq_u16(colsum0_h, one_u16);
+      /* Right-shift by 2 (divide by 4), narrow to 8-bit, and combine. */
+      uint8x16_t output_pixels0 = vcombine_u8(vshrn_n_u16(colsum0_l, 2),
+                                              vshrn_n_u16(colsum0_h, 2));
+      uint8x16_t output_pixels1 = vcombine_u8(vrshrn_n_u16(colsum1_l, 2),
+                                              vrshrn_n_u16(colsum1_h, 2));
+      /* Store pixel component values to memory. */
+      vst1q_u8(outptr0 + colctr, output_pixels0);
+      vst1q_u8(outptr1 + colctr, output_pixels1);
+    }
+  }
+}
+
+
+/* The diagram below shows a row of samples produced by h2v1 downsampling.
+ *
+ *                s0        s1
+ *            +---------+---------+
+ *            |         |         |
+ *            | p0   p1 | p2   p3 |
+ *            |         |         |
+ *            +---------+---------+
+ *
+ * Samples s0 and s1 were created by averaging the original pixel component
+ * values centered at positions p0-p3 above.  To approximate those original
+ * pixel component values, we duplicate the samples horizontally:
+ *     p0(upsampled) = p1(upsampled) = s0
+ *     p2(upsampled) = p3(upsampled) = s1
+ */
+
+void jsimd_h2v1_upsample_neon(int max_v_samp_factor, JDIMENSION output_width,
+                              JSAMPARRAY input_data,
+                              JSAMPARRAY *output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  JSAMPROW inptr, outptr;
+  int inrow;
+  unsigned colctr;
+
+  for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
+    inptr = input_data[inrow];
+    outptr = output_data[inrow];
+    for (colctr = 0; 2 * colctr < output_width; colctr += 16) {
+      uint8x16_t samples = vld1q_u8(inptr + colctr);
+      /* Duplicate the samples.  The store operation below interleaves them so
+       * that adjacent pixel component values take on the same sample value,
+       * per above.
+       */
+      uint8x16x2_t output_pixels = { { samples, samples } };
+      /* Store pixel component values to memory.
+       * Due to the way sample buffers are allocated, we don't need to worry
+       * about tail cases when output_width is not a multiple of 32.  See
+       * "Creation of 2-D sample arrays" in jmemmgr.c for details.
+       */
+      vst2q_u8(outptr + 2 * colctr, output_pixels);
+    }
+  }
+}
+
+
+/* The diagram below shows an array of samples produced by h2v2 downsampling.
+ *
+ *                s0        s1
+ *            +---------+---------+
+ *            | p0   p1 | p2   p3 |
+ *       sA   |         |         |
+ *            | p4   p5 | p6   p7 |
+ *            +---------+---------+
+ *            | p8   p9 | p10  p11|
+ *       sB   |         |         |
+ *            | p12  p13| p14  p15|
+ *            +---------+---------+
+ *
+ * Samples s0A-s1B were created by averaging the original pixel component
+ * values centered at positions p0-p15 above.  To approximate those original
+ * pixel component values, we duplicate the samples both horizontally and
+ * vertically:
+ *     p0(upsampled) = p1(upsampled) = p4(upsampled) = p5(upsampled) = s0A
+ *     p2(upsampled) = p3(upsampled) = p6(upsampled) = p7(upsampled) = s1A
+ *     p8(upsampled) = p9(upsampled) = p12(upsampled) = p13(upsampled) = s0B
+ *     p10(upsampled) = p11(upsampled) = p14(upsampled) = p15(upsampled) = s1B
+ */
+
+void jsimd_h2v2_upsample_neon(int max_v_samp_factor, JDIMENSION output_width,
+                              JSAMPARRAY input_data,
+                              JSAMPARRAY *output_data_ptr)
+{
+  JSAMPARRAY output_data = *output_data_ptr;
+  JSAMPROW inptr, outptr0, outptr1;
+  int inrow, outrow;
+  unsigned colctr;
+
+  for (inrow = 0, outrow = 0; outrow < max_v_samp_factor; inrow++) {
+    inptr = input_data[inrow];
+    outptr0 = output_data[outrow++];
+    outptr1 = output_data[outrow++];
+
+    for (colctr = 0; 2 * colctr < output_width; colctr += 16) {
+      uint8x16_t samples = vld1q_u8(inptr + colctr);
+      /* Duplicate the samples.  The store operation below interleaves them so
+       * that adjacent pixel component values take on the same sample value,
+       * per above.
+       */
+      uint8x16x2_t output_pixels = { { samples, samples } };
+      /* Store pixel component values for both output rows to memory.
+       * Due to the way sample buffers are allocated, we don't need to worry
+       * about tail cases when output_width is not a multiple of 32.  See
+       * "Creation of 2-D sample arrays" in jmemmgr.c for details.
+       */
+      vst2q_u8(outptr0 + 2 * colctr, output_pixels);
+      vst2q_u8(outptr1 + 2 * colctr, output_pixels);
+    }
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jfdctfst-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jfdctfst-neon.c
new file mode 100644
index 0000000..bb371be
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jfdctfst-neon.c
@@ -0,0 +1,214 @@
+/*
+ * jfdctfst-neon.c - fast integer FDCT (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+/* jsimd_fdct_ifast_neon() performs a fast, not so accurate forward DCT
+ * (Discrete Cosine Transform) on one block of samples.  It uses the same
+ * calculations and produces exactly the same output as IJG's original
+ * jpeg_fdct_ifast() function, which can be found in jfdctfst.c.
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.382683433 = 12544 * 2^-15
+ *    0.541196100 = 17795 * 2^-15
+ *    0.707106781 = 23168 * 2^-15
+ *    0.306562965 =  9984 * 2^-15
+ *
+ * See jfdctfst.c for further details of the DCT algorithm.  Where possible,
+ * the variable names and comments here in jsimd_fdct_ifast_neon() match up
+ * with those in jpeg_fdct_ifast().
+ */
+
+#define F_0_382  12544
+#define F_0_541  17792
+#define F_0_707  23168
+#define F_0_306  9984
+
+
+ALIGN(16) static const int16_t jsimd_fdct_ifast_neon_consts[] = {
+  F_0_382, F_0_541, F_0_707, F_0_306
+};
+
+void jsimd_fdct_ifast_neon(DCTELEM *data)
+{
+  /* Load an 8x8 block of samples into Neon registers.  De-interleaving loads
+   * are used, followed by vuzp to transpose the block such that we have a
+   * column of samples per vector - allowing all rows to be processed at once.
+   */
+  int16x8x4_t data1 = vld4q_s16(data);
+  int16x8x4_t data2 = vld4q_s16(data + 4 * DCTSIZE);
+
+  int16x8x2_t cols_04 = vuzpq_s16(data1.val[0], data2.val[0]);
+  int16x8x2_t cols_15 = vuzpq_s16(data1.val[1], data2.val[1]);
+  int16x8x2_t cols_26 = vuzpq_s16(data1.val[2], data2.val[2]);
+  int16x8x2_t cols_37 = vuzpq_s16(data1.val[3], data2.val[3]);
+
+  int16x8_t col0 = cols_04.val[0];
+  int16x8_t col1 = cols_15.val[0];
+  int16x8_t col2 = cols_26.val[0];
+  int16x8_t col3 = cols_37.val[0];
+  int16x8_t col4 = cols_04.val[1];
+  int16x8_t col5 = cols_15.val[1];
+  int16x8_t col6 = cols_26.val[1];
+  int16x8_t col7 = cols_37.val[1];
+
+  /* Pass 1: process rows. */
+
+  /* Load DCT conversion constants. */
+  const int16x4_t consts = vld1_s16(jsimd_fdct_ifast_neon_consts);
+
+  int16x8_t tmp0 = vaddq_s16(col0, col7);
+  int16x8_t tmp7 = vsubq_s16(col0, col7);
+  int16x8_t tmp1 = vaddq_s16(col1, col6);
+  int16x8_t tmp6 = vsubq_s16(col1, col6);
+  int16x8_t tmp2 = vaddq_s16(col2, col5);
+  int16x8_t tmp5 = vsubq_s16(col2, col5);
+  int16x8_t tmp3 = vaddq_s16(col3, col4);
+  int16x8_t tmp4 = vsubq_s16(col3, col4);
+
+  /* Even part */
+  int16x8_t tmp10 = vaddq_s16(tmp0, tmp3);    /* phase 2 */
+  int16x8_t tmp13 = vsubq_s16(tmp0, tmp3);
+  int16x8_t tmp11 = vaddq_s16(tmp1, tmp2);
+  int16x8_t tmp12 = vsubq_s16(tmp1, tmp2);
+
+  col0 = vaddq_s16(tmp10, tmp11);             /* phase 3 */
+  col4 = vsubq_s16(tmp10, tmp11);
+
+  int16x8_t z1 = vqdmulhq_lane_s16(vaddq_s16(tmp12, tmp13), consts, 2);
+  col2 = vaddq_s16(tmp13, z1);                /* phase 5 */
+  col6 = vsubq_s16(tmp13, z1);
+
+  /* Odd part */
+  tmp10 = vaddq_s16(tmp4, tmp5);              /* phase 2 */
+  tmp11 = vaddq_s16(tmp5, tmp6);
+  tmp12 = vaddq_s16(tmp6, tmp7);
+
+  int16x8_t z5 = vqdmulhq_lane_s16(vsubq_s16(tmp10, tmp12), consts, 0);
+  int16x8_t z2 = vqdmulhq_lane_s16(tmp10, consts, 1);
+  z2 = vaddq_s16(z2, z5);
+  int16x8_t z4 = vqdmulhq_lane_s16(tmp12, consts, 3);
+  z5 = vaddq_s16(tmp12, z5);
+  z4 = vaddq_s16(z4, z5);
+  int16x8_t z3 = vqdmulhq_lane_s16(tmp11, consts, 2);
+
+  int16x8_t z11 = vaddq_s16(tmp7, z3);        /* phase 5 */
+  int16x8_t z13 = vsubq_s16(tmp7, z3);
+
+  col5 = vaddq_s16(z13, z2);                  /* phase 6 */
+  col3 = vsubq_s16(z13, z2);
+  col1 = vaddq_s16(z11, z4);
+  col7 = vsubq_s16(z11, z4);
+
+  /* Transpose to work on columns in pass 2. */
+  int16x8x2_t cols_01 = vtrnq_s16(col0, col1);
+  int16x8x2_t cols_23 = vtrnq_s16(col2, col3);
+  int16x8x2_t cols_45 = vtrnq_s16(col4, col5);
+  int16x8x2_t cols_67 = vtrnq_s16(col6, col7);
+
+  int32x4x2_t cols_0145_l = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[0]),
+                                      vreinterpretq_s32_s16(cols_45.val[0]));
+  int32x4x2_t cols_0145_h = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[1]),
+                                      vreinterpretq_s32_s16(cols_45.val[1]));
+  int32x4x2_t cols_2367_l = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[0]),
+                                      vreinterpretq_s32_s16(cols_67.val[0]));
+  int32x4x2_t cols_2367_h = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[1]),
+                                      vreinterpretq_s32_s16(cols_67.val[1]));
+
+  int32x4x2_t rows_04 = vzipq_s32(cols_0145_l.val[0], cols_2367_l.val[0]);
+  int32x4x2_t rows_15 = vzipq_s32(cols_0145_h.val[0], cols_2367_h.val[0]);
+  int32x4x2_t rows_26 = vzipq_s32(cols_0145_l.val[1], cols_2367_l.val[1]);
+  int32x4x2_t rows_37 = vzipq_s32(cols_0145_h.val[1], cols_2367_h.val[1]);
+
+  int16x8_t row0 = vreinterpretq_s16_s32(rows_04.val[0]);
+  int16x8_t row1 = vreinterpretq_s16_s32(rows_15.val[0]);
+  int16x8_t row2 = vreinterpretq_s16_s32(rows_26.val[0]);
+  int16x8_t row3 = vreinterpretq_s16_s32(rows_37.val[0]);
+  int16x8_t row4 = vreinterpretq_s16_s32(rows_04.val[1]);
+  int16x8_t row5 = vreinterpretq_s16_s32(rows_15.val[1]);
+  int16x8_t row6 = vreinterpretq_s16_s32(rows_26.val[1]);
+  int16x8_t row7 = vreinterpretq_s16_s32(rows_37.val[1]);
+
+  /* Pass 2: process columns. */
+
+  tmp0 = vaddq_s16(row0, row7);
+  tmp7 = vsubq_s16(row0, row7);
+  tmp1 = vaddq_s16(row1, row6);
+  tmp6 = vsubq_s16(row1, row6);
+  tmp2 = vaddq_s16(row2, row5);
+  tmp5 = vsubq_s16(row2, row5);
+  tmp3 = vaddq_s16(row3, row4);
+  tmp4 = vsubq_s16(row3, row4);
+
+  /* Even part */
+  tmp10 = vaddq_s16(tmp0, tmp3);              /* phase 2 */
+  tmp13 = vsubq_s16(tmp0, tmp3);
+  tmp11 = vaddq_s16(tmp1, tmp2);
+  tmp12 = vsubq_s16(tmp1, tmp2);
+
+  row0 = vaddq_s16(tmp10, tmp11);             /* phase 3 */
+  row4 = vsubq_s16(tmp10, tmp11);
+
+  z1 = vqdmulhq_lane_s16(vaddq_s16(tmp12, tmp13), consts, 2);
+  row2 = vaddq_s16(tmp13, z1);                /* phase 5 */
+  row6 = vsubq_s16(tmp13, z1);
+
+  /* Odd part */
+  tmp10 = vaddq_s16(tmp4, tmp5);              /* phase 2 */
+  tmp11 = vaddq_s16(tmp5, tmp6);
+  tmp12 = vaddq_s16(tmp6, tmp7);
+
+  z5 = vqdmulhq_lane_s16(vsubq_s16(tmp10, tmp12), consts, 0);
+  z2 = vqdmulhq_lane_s16(tmp10, consts, 1);
+  z2 = vaddq_s16(z2, z5);
+  z4 = vqdmulhq_lane_s16(tmp12, consts, 3);
+  z5 = vaddq_s16(tmp12, z5);
+  z4 = vaddq_s16(z4, z5);
+  z3 = vqdmulhq_lane_s16(tmp11, consts, 2);
+
+  z11 = vaddq_s16(tmp7, z3);                  /* phase 5 */
+  z13 = vsubq_s16(tmp7, z3);
+
+  row5 = vaddq_s16(z13, z2);                  /* phase 6 */
+  row3 = vsubq_s16(z13, z2);
+  row1 = vaddq_s16(z11, z4);
+  row7 = vsubq_s16(z11, z4);
+
+  vst1q_s16(data + 0 * DCTSIZE, row0);
+  vst1q_s16(data + 1 * DCTSIZE, row1);
+  vst1q_s16(data + 2 * DCTSIZE, row2);
+  vst1q_s16(data + 3 * DCTSIZE, row3);
+  vst1q_s16(data + 4 * DCTSIZE, row4);
+  vst1q_s16(data + 5 * DCTSIZE, row5);
+  vst1q_s16(data + 6 * DCTSIZE, row6);
+  vst1q_s16(data + 7 * DCTSIZE, row7);
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jfdctint-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jfdctint-neon.c
new file mode 100644
index 0000000..ccfc07b
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jfdctint-neon.c
@@ -0,0 +1,376 @@
+/*
+ * jfdctint-neon.c - accurate integer FDCT (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+#include "neon-compat.h"
+
+#include <arm_neon.h>
+
+
+/* jsimd_fdct_islow_neon() performs a slower but more accurate forward DCT
+ * (Discrete Cosine Transform) on one block of samples.  It uses the same
+ * calculations and produces exactly the same output as IJG's original
+ * jpeg_fdct_islow() function, which can be found in jfdctint.c.
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.298631336 =  2446 * 2^-13
+ *    0.390180644 =  3196 * 2^-13
+ *    0.541196100 =  4433 * 2^-13
+ *    0.765366865 =  6270 * 2^-13
+ *    0.899976223 =  7373 * 2^-13
+ *    1.175875602 =  9633 * 2^-13
+ *    1.501321110 = 12299 * 2^-13
+ *    1.847759065 = 15137 * 2^-13
+ *    1.961570560 = 16069 * 2^-13
+ *    2.053119869 = 16819 * 2^-13
+ *    2.562915447 = 20995 * 2^-13
+ *    3.072711026 = 25172 * 2^-13
+ *
+ * See jfdctint.c for further details of the DCT algorithm.  Where possible,
+ * the variable names and comments here in jsimd_fdct_islow_neon() match up
+ * with those in jpeg_fdct_islow().
+ */
+
+#define CONST_BITS  13
+#define PASS1_BITS  2
+
+#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
+#define DESCALE_P2  (CONST_BITS + PASS1_BITS)
+
+#define F_0_298  2446
+#define F_0_390  3196
+#define F_0_541  4433
+#define F_0_765  6270
+#define F_0_899  7373
+#define F_1_175  9633
+#define F_1_501  12299
+#define F_1_847  15137
+#define F_1_961  16069
+#define F_2_053  16819
+#define F_2_562  20995
+#define F_3_072  25172
+
+
+ALIGN(16) static const int16_t jsimd_fdct_islow_neon_consts[] = {
+  F_0_298, -F_0_390,  F_0_541,  F_0_765,
+ -F_0_899,  F_1_175,  F_1_501, -F_1_847,
+ -F_1_961,  F_2_053, -F_2_562,  F_3_072
+};
+
+void jsimd_fdct_islow_neon(DCTELEM *data)
+{
+  /* Load DCT constants. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_fdct_islow_neon_consts);
+#else
+  /* GCC does not currently support the intrinsic vld1_<type>_x3(). */
+  const int16x4_t consts1 = vld1_s16(jsimd_fdct_islow_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_fdct_islow_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_fdct_islow_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  /* Load an 8x8 block of samples into Neon registers.  De-interleaving loads
+   * are used, followed by vuzp to transpose the block such that we have a
+   * column of samples per vector - allowing all rows to be processed at once.
+   */
+  int16x8x4_t s_rows_0123 = vld4q_s16(data);
+  int16x8x4_t s_rows_4567 = vld4q_s16(data + 4 * DCTSIZE);
+
+  int16x8x2_t cols_04 = vuzpq_s16(s_rows_0123.val[0], s_rows_4567.val[0]);
+  int16x8x2_t cols_15 = vuzpq_s16(s_rows_0123.val[1], s_rows_4567.val[1]);
+  int16x8x2_t cols_26 = vuzpq_s16(s_rows_0123.val[2], s_rows_4567.val[2]);
+  int16x8x2_t cols_37 = vuzpq_s16(s_rows_0123.val[3], s_rows_4567.val[3]);
+
+  int16x8_t col0 = cols_04.val[0];
+  int16x8_t col1 = cols_15.val[0];
+  int16x8_t col2 = cols_26.val[0];
+  int16x8_t col3 = cols_37.val[0];
+  int16x8_t col4 = cols_04.val[1];
+  int16x8_t col5 = cols_15.val[1];
+  int16x8_t col6 = cols_26.val[1];
+  int16x8_t col7 = cols_37.val[1];
+
+  /* Pass 1: process rows. */
+
+  int16x8_t tmp0 = vaddq_s16(col0, col7);
+  int16x8_t tmp7 = vsubq_s16(col0, col7);
+  int16x8_t tmp1 = vaddq_s16(col1, col6);
+  int16x8_t tmp6 = vsubq_s16(col1, col6);
+  int16x8_t tmp2 = vaddq_s16(col2, col5);
+  int16x8_t tmp5 = vsubq_s16(col2, col5);
+  int16x8_t tmp3 = vaddq_s16(col3, col4);
+  int16x8_t tmp4 = vsubq_s16(col3, col4);
+
+  /* Even part */
+  int16x8_t tmp10 = vaddq_s16(tmp0, tmp3);
+  int16x8_t tmp13 = vsubq_s16(tmp0, tmp3);
+  int16x8_t tmp11 = vaddq_s16(tmp1, tmp2);
+  int16x8_t tmp12 = vsubq_s16(tmp1, tmp2);
+
+  col0 = vshlq_n_s16(vaddq_s16(tmp10, tmp11), PASS1_BITS);
+  col4 = vshlq_n_s16(vsubq_s16(tmp10, tmp11), PASS1_BITS);
+
+  int16x8_t tmp12_add_tmp13 = vaddq_s16(tmp12, tmp13);
+  int32x4_t z1_l =
+    vmull_lane_s16(vget_low_s16(tmp12_add_tmp13), consts.val[0], 2);
+  int32x4_t z1_h =
+    vmull_lane_s16(vget_high_s16(tmp12_add_tmp13), consts.val[0], 2);
+
+  int32x4_t col2_scaled_l =
+    vmlal_lane_s16(z1_l, vget_low_s16(tmp13), consts.val[0], 3);
+  int32x4_t col2_scaled_h =
+    vmlal_lane_s16(z1_h, vget_high_s16(tmp13), consts.val[0], 3);
+  col2 = vcombine_s16(vrshrn_n_s32(col2_scaled_l, DESCALE_P1),
+                      vrshrn_n_s32(col2_scaled_h, DESCALE_P1));
+
+  int32x4_t col6_scaled_l =
+    vmlal_lane_s16(z1_l, vget_low_s16(tmp12), consts.val[1], 3);
+  int32x4_t col6_scaled_h =
+    vmlal_lane_s16(z1_h, vget_high_s16(tmp12), consts.val[1], 3);
+  col6 = vcombine_s16(vrshrn_n_s32(col6_scaled_l, DESCALE_P1),
+                      vrshrn_n_s32(col6_scaled_h, DESCALE_P1));
+
+  /* Odd part */
+  int16x8_t z1 = vaddq_s16(tmp4, tmp7);
+  int16x8_t z2 = vaddq_s16(tmp5, tmp6);
+  int16x8_t z3 = vaddq_s16(tmp4, tmp6);
+  int16x8_t z4 = vaddq_s16(tmp5, tmp7);
+  /* sqrt(2) * c3 */
+  int32x4_t z5_l = vmull_lane_s16(vget_low_s16(z3), consts.val[1], 1);
+  int32x4_t z5_h = vmull_lane_s16(vget_high_s16(z3), consts.val[1], 1);
+  z5_l = vmlal_lane_s16(z5_l, vget_low_s16(z4), consts.val[1], 1);
+  z5_h = vmlal_lane_s16(z5_h, vget_high_s16(z4), consts.val[1], 1);
+
+  /* sqrt(2) * (-c1+c3+c5-c7) */
+  int32x4_t tmp4_l = vmull_lane_s16(vget_low_s16(tmp4), consts.val[0], 0);
+  int32x4_t tmp4_h = vmull_lane_s16(vget_high_s16(tmp4), consts.val[0], 0);
+  /* sqrt(2) * ( c1+c3-c5+c7) */
+  int32x4_t tmp5_l = vmull_lane_s16(vget_low_s16(tmp5), consts.val[2], 1);
+  int32x4_t tmp5_h = vmull_lane_s16(vget_high_s16(tmp5), consts.val[2], 1);
+  /* sqrt(2) * ( c1+c3+c5-c7) */
+  int32x4_t tmp6_l = vmull_lane_s16(vget_low_s16(tmp6), consts.val[2], 3);
+  int32x4_t tmp6_h = vmull_lane_s16(vget_high_s16(tmp6), consts.val[2], 3);
+  /* sqrt(2) * ( c1+c3-c5-c7) */
+  int32x4_t tmp7_l = vmull_lane_s16(vget_low_s16(tmp7), consts.val[1], 2);
+  int32x4_t tmp7_h = vmull_lane_s16(vget_high_s16(tmp7), consts.val[1], 2);
+
+  /* sqrt(2) * (c7-c3) */
+  z1_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 0);
+  z1_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 0);
+  /* sqrt(2) * (-c1-c3) */
+  int32x4_t z2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[2], 2);
+  int32x4_t z2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[2], 2);
+  /* sqrt(2) * (-c3-c5) */
+  int32x4_t z3_l = vmull_lane_s16(vget_low_s16(z3), consts.val[2], 0);
+  int32x4_t z3_h = vmull_lane_s16(vget_high_s16(z3), consts.val[2], 0);
+  /* sqrt(2) * (c5-c3) */
+  int32x4_t z4_l = vmull_lane_s16(vget_low_s16(z4), consts.val[0], 1);
+  int32x4_t z4_h = vmull_lane_s16(vget_high_s16(z4), consts.val[0], 1);
+
+  z3_l = vaddq_s32(z3_l, z5_l);
+  z3_h = vaddq_s32(z3_h, z5_h);
+  z4_l = vaddq_s32(z4_l, z5_l);
+  z4_h = vaddq_s32(z4_h, z5_h);
+
+  tmp4_l = vaddq_s32(tmp4_l, z1_l);
+  tmp4_h = vaddq_s32(tmp4_h, z1_h);
+  tmp4_l = vaddq_s32(tmp4_l, z3_l);
+  tmp4_h = vaddq_s32(tmp4_h, z3_h);
+  col7 = vcombine_s16(vrshrn_n_s32(tmp4_l, DESCALE_P1),
+                      vrshrn_n_s32(tmp4_h, DESCALE_P1));
+
+  tmp5_l = vaddq_s32(tmp5_l, z2_l);
+  tmp5_h = vaddq_s32(tmp5_h, z2_h);
+  tmp5_l = vaddq_s32(tmp5_l, z4_l);
+  tmp5_h = vaddq_s32(tmp5_h, z4_h);
+  col5 = vcombine_s16(vrshrn_n_s32(tmp5_l, DESCALE_P1),
+                      vrshrn_n_s32(tmp5_h, DESCALE_P1));
+
+  tmp6_l = vaddq_s32(tmp6_l, z2_l);
+  tmp6_h = vaddq_s32(tmp6_h, z2_h);
+  tmp6_l = vaddq_s32(tmp6_l, z3_l);
+  tmp6_h = vaddq_s32(tmp6_h, z3_h);
+  col3 = vcombine_s16(vrshrn_n_s32(tmp6_l, DESCALE_P1),
+                      vrshrn_n_s32(tmp6_h, DESCALE_P1));
+
+  tmp7_l = vaddq_s32(tmp7_l, z1_l);
+  tmp7_h = vaddq_s32(tmp7_h, z1_h);
+  tmp7_l = vaddq_s32(tmp7_l, z4_l);
+  tmp7_h = vaddq_s32(tmp7_h, z4_h);
+  col1 = vcombine_s16(vrshrn_n_s32(tmp7_l, DESCALE_P1),
+                      vrshrn_n_s32(tmp7_h, DESCALE_P1));
+
+  /* Transpose to work on columns in pass 2. */
+  int16x8x2_t cols_01 = vtrnq_s16(col0, col1);
+  int16x8x2_t cols_23 = vtrnq_s16(col2, col3);
+  int16x8x2_t cols_45 = vtrnq_s16(col4, col5);
+  int16x8x2_t cols_67 = vtrnq_s16(col6, col7);
+
+  int32x4x2_t cols_0145_l = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[0]),
+                                      vreinterpretq_s32_s16(cols_45.val[0]));
+  int32x4x2_t cols_0145_h = vtrnq_s32(vreinterpretq_s32_s16(cols_01.val[1]),
+                                      vreinterpretq_s32_s16(cols_45.val[1]));
+  int32x4x2_t cols_2367_l = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[0]),
+                                      vreinterpretq_s32_s16(cols_67.val[0]));
+  int32x4x2_t cols_2367_h = vtrnq_s32(vreinterpretq_s32_s16(cols_23.val[1]),
+                                      vreinterpretq_s32_s16(cols_67.val[1]));
+
+  int32x4x2_t rows_04 = vzipq_s32(cols_0145_l.val[0], cols_2367_l.val[0]);
+  int32x4x2_t rows_15 = vzipq_s32(cols_0145_h.val[0], cols_2367_h.val[0]);
+  int32x4x2_t rows_26 = vzipq_s32(cols_0145_l.val[1], cols_2367_l.val[1]);
+  int32x4x2_t rows_37 = vzipq_s32(cols_0145_h.val[1], cols_2367_h.val[1]);
+
+  int16x8_t row0 = vreinterpretq_s16_s32(rows_04.val[0]);
+  int16x8_t row1 = vreinterpretq_s16_s32(rows_15.val[0]);
+  int16x8_t row2 = vreinterpretq_s16_s32(rows_26.val[0]);
+  int16x8_t row3 = vreinterpretq_s16_s32(rows_37.val[0]);
+  int16x8_t row4 = vreinterpretq_s16_s32(rows_04.val[1]);
+  int16x8_t row5 = vreinterpretq_s16_s32(rows_15.val[1]);
+  int16x8_t row6 = vreinterpretq_s16_s32(rows_26.val[1]);
+  int16x8_t row7 = vreinterpretq_s16_s32(rows_37.val[1]);
+
+  /* Pass 2: process columns. */
+
+  tmp0 = vaddq_s16(row0, row7);
+  tmp7 = vsubq_s16(row0, row7);
+  tmp1 = vaddq_s16(row1, row6);
+  tmp6 = vsubq_s16(row1, row6);
+  tmp2 = vaddq_s16(row2, row5);
+  tmp5 = vsubq_s16(row2, row5);
+  tmp3 = vaddq_s16(row3, row4);
+  tmp4 = vsubq_s16(row3, row4);
+
+  /* Even part */
+  tmp10 = vaddq_s16(tmp0, tmp3);
+  tmp13 = vsubq_s16(tmp0, tmp3);
+  tmp11 = vaddq_s16(tmp1, tmp2);
+  tmp12 = vsubq_s16(tmp1, tmp2);
+
+  row0 = vrshrq_n_s16(vaddq_s16(tmp10, tmp11), PASS1_BITS);
+  row4 = vrshrq_n_s16(vsubq_s16(tmp10, tmp11), PASS1_BITS);
+
+  tmp12_add_tmp13 = vaddq_s16(tmp12, tmp13);
+  z1_l = vmull_lane_s16(vget_low_s16(tmp12_add_tmp13), consts.val[0], 2);
+  z1_h = vmull_lane_s16(vget_high_s16(tmp12_add_tmp13), consts.val[0], 2);
+
+  int32x4_t row2_scaled_l =
+    vmlal_lane_s16(z1_l, vget_low_s16(tmp13), consts.val[0], 3);
+  int32x4_t row2_scaled_h =
+    vmlal_lane_s16(z1_h, vget_high_s16(tmp13), consts.val[0], 3);
+  row2 = vcombine_s16(vrshrn_n_s32(row2_scaled_l, DESCALE_P2),
+                      vrshrn_n_s32(row2_scaled_h, DESCALE_P2));
+
+  int32x4_t row6_scaled_l =
+    vmlal_lane_s16(z1_l, vget_low_s16(tmp12), consts.val[1], 3);
+  int32x4_t row6_scaled_h =
+    vmlal_lane_s16(z1_h, vget_high_s16(tmp12), consts.val[1], 3);
+  row6 = vcombine_s16(vrshrn_n_s32(row6_scaled_l, DESCALE_P2),
+                      vrshrn_n_s32(row6_scaled_h, DESCALE_P2));
+
+  /* Odd part */
+  z1 = vaddq_s16(tmp4, tmp7);
+  z2 = vaddq_s16(tmp5, tmp6);
+  z3 = vaddq_s16(tmp4, tmp6);
+  z4 = vaddq_s16(tmp5, tmp7);
+  /* sqrt(2) * c3 */
+  z5_l = vmull_lane_s16(vget_low_s16(z3), consts.val[1], 1);
+  z5_h = vmull_lane_s16(vget_high_s16(z3), consts.val[1], 1);
+  z5_l = vmlal_lane_s16(z5_l, vget_low_s16(z4), consts.val[1], 1);
+  z5_h = vmlal_lane_s16(z5_h, vget_high_s16(z4), consts.val[1], 1);
+
+  /* sqrt(2) * (-c1+c3+c5-c7) */
+  tmp4_l = vmull_lane_s16(vget_low_s16(tmp4), consts.val[0], 0);
+  tmp4_h = vmull_lane_s16(vget_high_s16(tmp4), consts.val[0], 0);
+  /* sqrt(2) * ( c1+c3-c5+c7) */
+  tmp5_l = vmull_lane_s16(vget_low_s16(tmp5), consts.val[2], 1);
+  tmp5_h = vmull_lane_s16(vget_high_s16(tmp5), consts.val[2], 1);
+  /* sqrt(2) * ( c1+c3+c5-c7) */
+  tmp6_l = vmull_lane_s16(vget_low_s16(tmp6), consts.val[2], 3);
+  tmp6_h = vmull_lane_s16(vget_high_s16(tmp6), consts.val[2], 3);
+  /* sqrt(2) * ( c1+c3-c5-c7) */
+  tmp7_l = vmull_lane_s16(vget_low_s16(tmp7), consts.val[1], 2);
+  tmp7_h = vmull_lane_s16(vget_high_s16(tmp7), consts.val[1], 2);
+
+  /* sqrt(2) * (c7-c3) */
+  z1_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 0);
+  z1_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 0);
+  /* sqrt(2) * (-c1-c3) */
+  z2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[2], 2);
+  z2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[2], 2);
+  /* sqrt(2) * (-c3-c5) */
+  z3_l = vmull_lane_s16(vget_low_s16(z3), consts.val[2], 0);
+  z3_h = vmull_lane_s16(vget_high_s16(z3), consts.val[2], 0);
+  /* sqrt(2) * (c5-c3) */
+  z4_l = vmull_lane_s16(vget_low_s16(z4), consts.val[0], 1);
+  z4_h = vmull_lane_s16(vget_high_s16(z4), consts.val[0], 1);
+
+  z3_l = vaddq_s32(z3_l, z5_l);
+  z3_h = vaddq_s32(z3_h, z5_h);
+  z4_l = vaddq_s32(z4_l, z5_l);
+  z4_h = vaddq_s32(z4_h, z5_h);
+
+  tmp4_l = vaddq_s32(tmp4_l, z1_l);
+  tmp4_h = vaddq_s32(tmp4_h, z1_h);
+  tmp4_l = vaddq_s32(tmp4_l, z3_l);
+  tmp4_h = vaddq_s32(tmp4_h, z3_h);
+  row7 = vcombine_s16(vrshrn_n_s32(tmp4_l, DESCALE_P2),
+                      vrshrn_n_s32(tmp4_h, DESCALE_P2));
+
+  tmp5_l = vaddq_s32(tmp5_l, z2_l);
+  tmp5_h = vaddq_s32(tmp5_h, z2_h);
+  tmp5_l = vaddq_s32(tmp5_l, z4_l);
+  tmp5_h = vaddq_s32(tmp5_h, z4_h);
+  row5 = vcombine_s16(vrshrn_n_s32(tmp5_l, DESCALE_P2),
+                      vrshrn_n_s32(tmp5_h, DESCALE_P2));
+
+  tmp6_l = vaddq_s32(tmp6_l, z2_l);
+  tmp6_h = vaddq_s32(tmp6_h, z2_h);
+  tmp6_l = vaddq_s32(tmp6_l, z3_l);
+  tmp6_h = vaddq_s32(tmp6_h, z3_h);
+  row3 = vcombine_s16(vrshrn_n_s32(tmp6_l, DESCALE_P2),
+                      vrshrn_n_s32(tmp6_h, DESCALE_P2));
+
+  tmp7_l = vaddq_s32(tmp7_l, z1_l);
+  tmp7_h = vaddq_s32(tmp7_h, z1_h);
+  tmp7_l = vaddq_s32(tmp7_l, z4_l);
+  tmp7_h = vaddq_s32(tmp7_h, z4_h);
+  row1 = vcombine_s16(vrshrn_n_s32(tmp7_l, DESCALE_P2),
+                      vrshrn_n_s32(tmp7_h, DESCALE_P2));
+
+  vst1q_s16(data + 0 * DCTSIZE, row0);
+  vst1q_s16(data + 1 * DCTSIZE, row1);
+  vst1q_s16(data + 2 * DCTSIZE, row2);
+  vst1q_s16(data + 3 * DCTSIZE, row3);
+  vst1q_s16(data + 4 * DCTSIZE, row4);
+  vst1q_s16(data + 5 * DCTSIZE, row5);
+  vst1q_s16(data + 6 * DCTSIZE, row6);
+  vst1q_s16(data + 7 * DCTSIZE, row7);
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jidctfst-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jidctfst-neon.c
new file mode 100644
index 0000000..a91be53
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jidctfst-neon.c
@@ -0,0 +1,472 @@
+/*
+ * jidctfst-neon.c - fast integer IDCT (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+
+#include <arm_neon.h>
+
+
+/* jsimd_idct_ifast_neon() performs dequantization and a fast, not so accurate
+ * inverse DCT (Discrete Cosine Transform) on one block of coefficients.  It
+ * uses the same calculations and produces exactly the same output as IJG's
+ * original jpeg_idct_ifast() function, which can be found in jidctfst.c.
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.082392200 =  2688 * 2^-15
+ *    0.414213562 = 13568 * 2^-15
+ *    0.847759065 = 27776 * 2^-15
+ *    0.613125930 = 20096 * 2^-15
+ *
+ * See jidctfst.c for further details of the IDCT algorithm.  Where possible,
+ * the variable names and comments here in jsimd_idct_ifast_neon() match up
+ * with those in jpeg_idct_ifast().
+ */
+
+#define PASS1_BITS  2
+
+#define F_0_082  2688
+#define F_0_414  13568
+#define F_0_847  27776
+#define F_0_613  20096
+
+
+ALIGN(16) static const int16_t jsimd_idct_ifast_neon_consts[] = {
+  F_0_082, F_0_414, F_0_847, F_0_613
+};
+
+void jsimd_idct_ifast_neon(void *dct_table, JCOEFPTR coef_block,
+                           JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  IFAST_MULT_TYPE *quantptr = dct_table;
+
+  /* Load DCT coefficients. */
+  int16x8_t row0 = vld1q_s16(coef_block + 0 * DCTSIZE);
+  int16x8_t row1 = vld1q_s16(coef_block + 1 * DCTSIZE);
+  int16x8_t row2 = vld1q_s16(coef_block + 2 * DCTSIZE);
+  int16x8_t row3 = vld1q_s16(coef_block + 3 * DCTSIZE);
+  int16x8_t row4 = vld1q_s16(coef_block + 4 * DCTSIZE);
+  int16x8_t row5 = vld1q_s16(coef_block + 5 * DCTSIZE);
+  int16x8_t row6 = vld1q_s16(coef_block + 6 * DCTSIZE);
+  int16x8_t row7 = vld1q_s16(coef_block + 7 * DCTSIZE);
+
+  /* Load quantization table values for DC coefficients. */
+  int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
+  /* Dequantize DC coefficients. */
+  row0 = vmulq_s16(row0, quant_row0);
+
+  /* Construct bitmap to test if all AC coefficients are 0. */
+  int16x8_t bitmap = vorrq_s16(row1, row2);
+  bitmap = vorrq_s16(bitmap, row3);
+  bitmap = vorrq_s16(bitmap, row4);
+  bitmap = vorrq_s16(bitmap, row5);
+  bitmap = vorrq_s16(bitmap, row6);
+  bitmap = vorrq_s16(bitmap, row7);
+
+  int64_t left_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 0);
+  int64_t right_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 1);
+
+  /* Load IDCT conversion constants. */
+  const int16x4_t consts = vld1_s16(jsimd_idct_ifast_neon_consts);
+
+  if (left_ac_bitmap == 0 && right_ac_bitmap == 0) {
+    /* All AC coefficients are zero.
+     * Compute DC values and duplicate into vectors.
+     */
+    int16x8_t dcval = row0;
+    row1 = dcval;
+    row2 = dcval;
+    row3 = dcval;
+    row4 = dcval;
+    row5 = dcval;
+    row6 = dcval;
+    row7 = dcval;
+  } else if (left_ac_bitmap == 0) {
+    /* AC coefficients are zero for columns 0, 1, 2, and 3.
+     * Use DC values for these columns.
+     */
+    int16x4_t dcval = vget_low_s16(row0);
+
+    /* Commence regular fast IDCT computation for columns 4, 5, 6, and 7. */
+
+    /* Load quantization table. */
+    int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
+    int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
+    int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
+    int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE + 4);
+    int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
+    int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
+    int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
+
+    /* Even part: dequantize DCT coefficients. */
+    int16x4_t tmp0 = vget_high_s16(row0);
+    int16x4_t tmp1 = vmul_s16(vget_high_s16(row2), quant_row2);
+    int16x4_t tmp2 = vmul_s16(vget_high_s16(row4), quant_row4);
+    int16x4_t tmp3 = vmul_s16(vget_high_s16(row6), quant_row6);
+
+    int16x4_t tmp10 = vadd_s16(tmp0, tmp2);   /* phase 3 */
+    int16x4_t tmp11 = vsub_s16(tmp0, tmp2);
+
+    int16x4_t tmp13 = vadd_s16(tmp1, tmp3);   /* phases 5-3 */
+    int16x4_t tmp1_sub_tmp3 = vsub_s16(tmp1, tmp3);
+    int16x4_t tmp12 = vqdmulh_lane_s16(tmp1_sub_tmp3, consts, 1);
+    tmp12 = vadd_s16(tmp12, tmp1_sub_tmp3);
+    tmp12 = vsub_s16(tmp12, tmp13);
+
+    tmp0 = vadd_s16(tmp10, tmp13);            /* phase 2 */
+    tmp3 = vsub_s16(tmp10, tmp13);
+    tmp1 = vadd_s16(tmp11, tmp12);
+    tmp2 = vsub_s16(tmp11, tmp12);
+
+    /* Odd part: dequantize DCT coefficients. */
+    int16x4_t tmp4 = vmul_s16(vget_high_s16(row1), quant_row1);
+    int16x4_t tmp5 = vmul_s16(vget_high_s16(row3), quant_row3);
+    int16x4_t tmp6 = vmul_s16(vget_high_s16(row5), quant_row5);
+    int16x4_t tmp7 = vmul_s16(vget_high_s16(row7), quant_row7);
+
+    int16x4_t z13 = vadd_s16(tmp6, tmp5);     /* phase 6 */
+    int16x4_t neg_z10 = vsub_s16(tmp5, tmp6);
+    int16x4_t z11 = vadd_s16(tmp4, tmp7);
+    int16x4_t z12 = vsub_s16(tmp4, tmp7);
+
+    tmp7 = vadd_s16(z11, z13);                /* phase 5 */
+    int16x4_t z11_sub_z13 = vsub_s16(z11, z13);
+    tmp11 = vqdmulh_lane_s16(z11_sub_z13, consts, 1);
+    tmp11 = vadd_s16(tmp11, z11_sub_z13);
+
+    int16x4_t z10_add_z12 = vsub_s16(z12, neg_z10);
+    int16x4_t z5 = vqdmulh_lane_s16(z10_add_z12, consts, 2);
+    z5 = vadd_s16(z5, z10_add_z12);
+    tmp10 = vqdmulh_lane_s16(z12, consts, 0);
+    tmp10 = vadd_s16(tmp10, z12);
+    tmp10 = vsub_s16(tmp10, z5);
+    tmp12 = vqdmulh_lane_s16(neg_z10, consts, 3);
+    tmp12 = vadd_s16(tmp12, vadd_s16(neg_z10, neg_z10));
+    tmp12 = vadd_s16(tmp12, z5);
+
+    tmp6 = vsub_s16(tmp12, tmp7);             /* phase 2 */
+    tmp5 = vsub_s16(tmp11, tmp6);
+    tmp4 = vadd_s16(tmp10, tmp5);
+
+    row0 = vcombine_s16(dcval, vadd_s16(tmp0, tmp7));
+    row7 = vcombine_s16(dcval, vsub_s16(tmp0, tmp7));
+    row1 = vcombine_s16(dcval, vadd_s16(tmp1, tmp6));
+    row6 = vcombine_s16(dcval, vsub_s16(tmp1, tmp6));
+    row2 = vcombine_s16(dcval, vadd_s16(tmp2, tmp5));
+    row5 = vcombine_s16(dcval, vsub_s16(tmp2, tmp5));
+    row4 = vcombine_s16(dcval, vadd_s16(tmp3, tmp4));
+    row3 = vcombine_s16(dcval, vsub_s16(tmp3, tmp4));
+  } else if (right_ac_bitmap == 0) {
+    /* AC coefficients are zero for columns 4, 5, 6, and 7.
+     * Use DC values for these columns.
+     */
+    int16x4_t dcval = vget_high_s16(row0);
+
+    /* Commence regular fast IDCT computation for columns 0, 1, 2, and 3. */
+
+    /* Load quantization table. */
+    int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
+    int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
+    int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
+    int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE);
+    int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
+    int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
+    int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
+
+    /* Even part: dequantize DCT coefficients. */
+    int16x4_t tmp0 = vget_low_s16(row0);
+    int16x4_t tmp1 = vmul_s16(vget_low_s16(row2), quant_row2);
+    int16x4_t tmp2 = vmul_s16(vget_low_s16(row4), quant_row4);
+    int16x4_t tmp3 = vmul_s16(vget_low_s16(row6), quant_row6);
+
+    int16x4_t tmp10 = vadd_s16(tmp0, tmp2);   /* phase 3 */
+    int16x4_t tmp11 = vsub_s16(tmp0, tmp2);
+
+    int16x4_t tmp13 = vadd_s16(tmp1, tmp3);   /* phases 5-3 */
+    int16x4_t tmp1_sub_tmp3 = vsub_s16(tmp1, tmp3);
+    int16x4_t tmp12 = vqdmulh_lane_s16(tmp1_sub_tmp3, consts, 1);
+    tmp12 = vadd_s16(tmp12, tmp1_sub_tmp3);
+    tmp12 = vsub_s16(tmp12, tmp13);
+
+    tmp0 = vadd_s16(tmp10, tmp13);            /* phase 2 */
+    tmp3 = vsub_s16(tmp10, tmp13);
+    tmp1 = vadd_s16(tmp11, tmp12);
+    tmp2 = vsub_s16(tmp11, tmp12);
+
+    /* Odd part: dequantize DCT coefficients. */
+    int16x4_t tmp4 = vmul_s16(vget_low_s16(row1), quant_row1);
+    int16x4_t tmp5 = vmul_s16(vget_low_s16(row3), quant_row3);
+    int16x4_t tmp6 = vmul_s16(vget_low_s16(row5), quant_row5);
+    int16x4_t tmp7 = vmul_s16(vget_low_s16(row7), quant_row7);
+
+    int16x4_t z13 = vadd_s16(tmp6, tmp5);     /* phase 6 */
+    int16x4_t neg_z10 = vsub_s16(tmp5, tmp6);
+    int16x4_t z11 = vadd_s16(tmp4, tmp7);
+    int16x4_t z12 = vsub_s16(tmp4, tmp7);
+
+    tmp7 = vadd_s16(z11, z13);                /* phase 5 */
+    int16x4_t z11_sub_z13 = vsub_s16(z11, z13);
+    tmp11 = vqdmulh_lane_s16(z11_sub_z13, consts, 1);
+    tmp11 = vadd_s16(tmp11, z11_sub_z13);
+
+    int16x4_t z10_add_z12 = vsub_s16(z12, neg_z10);
+    int16x4_t z5 = vqdmulh_lane_s16(z10_add_z12, consts, 2);
+    z5 = vadd_s16(z5, z10_add_z12);
+    tmp10 = vqdmulh_lane_s16(z12, consts, 0);
+    tmp10 = vadd_s16(tmp10, z12);
+    tmp10 = vsub_s16(tmp10, z5);
+    tmp12 = vqdmulh_lane_s16(neg_z10, consts, 3);
+    tmp12 = vadd_s16(tmp12, vadd_s16(neg_z10, neg_z10));
+    tmp12 = vadd_s16(tmp12, z5);
+
+    tmp6 = vsub_s16(tmp12, tmp7);             /* phase 2 */
+    tmp5 = vsub_s16(tmp11, tmp6);
+    tmp4 = vadd_s16(tmp10, tmp5);
+
+    row0 = vcombine_s16(vadd_s16(tmp0, tmp7), dcval);
+    row7 = vcombine_s16(vsub_s16(tmp0, tmp7), dcval);
+    row1 = vcombine_s16(vadd_s16(tmp1, tmp6), dcval);
+    row6 = vcombine_s16(vsub_s16(tmp1, tmp6), dcval);
+    row2 = vcombine_s16(vadd_s16(tmp2, tmp5), dcval);
+    row5 = vcombine_s16(vsub_s16(tmp2, tmp5), dcval);
+    row4 = vcombine_s16(vadd_s16(tmp3, tmp4), dcval);
+    row3 = vcombine_s16(vsub_s16(tmp3, tmp4), dcval);
+  } else {
+    /* Some AC coefficients are non-zero; full IDCT calculation required. */
+
+    /* Load quantization table. */
+    int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
+    int16x8_t quant_row2 = vld1q_s16(quantptr + 2 * DCTSIZE);
+    int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
+    int16x8_t quant_row4 = vld1q_s16(quantptr + 4 * DCTSIZE);
+    int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
+    int16x8_t quant_row6 = vld1q_s16(quantptr + 6 * DCTSIZE);
+    int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
+
+    /* Even part: dequantize DCT coefficients. */
+    int16x8_t tmp0 = row0;
+    int16x8_t tmp1 = vmulq_s16(row2, quant_row2);
+    int16x8_t tmp2 = vmulq_s16(row4, quant_row4);
+    int16x8_t tmp3 = vmulq_s16(row6, quant_row6);
+
+    int16x8_t tmp10 = vaddq_s16(tmp0, tmp2);   /* phase 3 */
+    int16x8_t tmp11 = vsubq_s16(tmp0, tmp2);
+
+    int16x8_t tmp13 = vaddq_s16(tmp1, tmp3);   /* phases 5-3 */
+    int16x8_t tmp1_sub_tmp3 = vsubq_s16(tmp1, tmp3);
+    int16x8_t tmp12 = vqdmulhq_lane_s16(tmp1_sub_tmp3, consts, 1);
+    tmp12 = vaddq_s16(tmp12, tmp1_sub_tmp3);
+    tmp12 = vsubq_s16(tmp12, tmp13);
+
+    tmp0 = vaddq_s16(tmp10, tmp13);            /* phase 2 */
+    tmp3 = vsubq_s16(tmp10, tmp13);
+    tmp1 = vaddq_s16(tmp11, tmp12);
+    tmp2 = vsubq_s16(tmp11, tmp12);
+
+    /* Odd part: dequantize DCT coefficients. */
+    int16x8_t tmp4 = vmulq_s16(row1, quant_row1);
+    int16x8_t tmp5 = vmulq_s16(row3, quant_row3);
+    int16x8_t tmp6 = vmulq_s16(row5, quant_row5);
+    int16x8_t tmp7 = vmulq_s16(row7, quant_row7);
+
+    int16x8_t z13 = vaddq_s16(tmp6, tmp5);     /* phase 6 */
+    int16x8_t neg_z10 = vsubq_s16(tmp5, tmp6);
+    int16x8_t z11 = vaddq_s16(tmp4, tmp7);
+    int16x8_t z12 = vsubq_s16(tmp4, tmp7);
+
+    tmp7 = vaddq_s16(z11, z13);                /* phase 5 */
+    int16x8_t z11_sub_z13 = vsubq_s16(z11, z13);
+    tmp11 = vqdmulhq_lane_s16(z11_sub_z13, consts, 1);
+    tmp11 = vaddq_s16(tmp11, z11_sub_z13);
+
+    int16x8_t z10_add_z12 = vsubq_s16(z12, neg_z10);
+    int16x8_t z5 = vqdmulhq_lane_s16(z10_add_z12, consts, 2);
+    z5 = vaddq_s16(z5, z10_add_z12);
+    tmp10 = vqdmulhq_lane_s16(z12, consts, 0);
+    tmp10 = vaddq_s16(tmp10, z12);
+    tmp10 = vsubq_s16(tmp10, z5);
+    tmp12 = vqdmulhq_lane_s16(neg_z10, consts, 3);
+    tmp12 = vaddq_s16(tmp12, vaddq_s16(neg_z10, neg_z10));
+    tmp12 = vaddq_s16(tmp12, z5);
+
+    tmp6 = vsubq_s16(tmp12, tmp7);             /* phase 2 */
+    tmp5 = vsubq_s16(tmp11, tmp6);
+    tmp4 = vaddq_s16(tmp10, tmp5);
+
+    row0 = vaddq_s16(tmp0, tmp7);
+    row7 = vsubq_s16(tmp0, tmp7);
+    row1 = vaddq_s16(tmp1, tmp6);
+    row6 = vsubq_s16(tmp1, tmp6);
+    row2 = vaddq_s16(tmp2, tmp5);
+    row5 = vsubq_s16(tmp2, tmp5);
+    row4 = vaddq_s16(tmp3, tmp4);
+    row3 = vsubq_s16(tmp3, tmp4);
+  }
+
+  /* Transpose rows to work on columns in pass 2. */
+  int16x8x2_t rows_01 = vtrnq_s16(row0, row1);
+  int16x8x2_t rows_23 = vtrnq_s16(row2, row3);
+  int16x8x2_t rows_45 = vtrnq_s16(row4, row5);
+  int16x8x2_t rows_67 = vtrnq_s16(row6, row7);
+
+  int32x4x2_t rows_0145_l = vtrnq_s32(vreinterpretq_s32_s16(rows_01.val[0]),
+                                      vreinterpretq_s32_s16(rows_45.val[0]));
+  int32x4x2_t rows_0145_h = vtrnq_s32(vreinterpretq_s32_s16(rows_01.val[1]),
+                                      vreinterpretq_s32_s16(rows_45.val[1]));
+  int32x4x2_t rows_2367_l = vtrnq_s32(vreinterpretq_s32_s16(rows_23.val[0]),
+                                      vreinterpretq_s32_s16(rows_67.val[0]));
+  int32x4x2_t rows_2367_h = vtrnq_s32(vreinterpretq_s32_s16(rows_23.val[1]),
+                                      vreinterpretq_s32_s16(rows_67.val[1]));
+
+  int32x4x2_t cols_04 = vzipq_s32(rows_0145_l.val[0], rows_2367_l.val[0]);
+  int32x4x2_t cols_15 = vzipq_s32(rows_0145_h.val[0], rows_2367_h.val[0]);
+  int32x4x2_t cols_26 = vzipq_s32(rows_0145_l.val[1], rows_2367_l.val[1]);
+  int32x4x2_t cols_37 = vzipq_s32(rows_0145_h.val[1], rows_2367_h.val[1]);
+
+  int16x8_t col0 = vreinterpretq_s16_s32(cols_04.val[0]);
+  int16x8_t col1 = vreinterpretq_s16_s32(cols_15.val[0]);
+  int16x8_t col2 = vreinterpretq_s16_s32(cols_26.val[0]);
+  int16x8_t col3 = vreinterpretq_s16_s32(cols_37.val[0]);
+  int16x8_t col4 = vreinterpretq_s16_s32(cols_04.val[1]);
+  int16x8_t col5 = vreinterpretq_s16_s32(cols_15.val[1]);
+  int16x8_t col6 = vreinterpretq_s16_s32(cols_26.val[1]);
+  int16x8_t col7 = vreinterpretq_s16_s32(cols_37.val[1]);
+
+  /* 1-D IDCT, pass 2 */
+
+  /* Even part */
+  int16x8_t tmp10 = vaddq_s16(col0, col4);
+  int16x8_t tmp11 = vsubq_s16(col0, col4);
+
+  int16x8_t tmp13 = vaddq_s16(col2, col6);
+  int16x8_t col2_sub_col6 = vsubq_s16(col2, col6);
+  int16x8_t tmp12 = vqdmulhq_lane_s16(col2_sub_col6, consts, 1);
+  tmp12 = vaddq_s16(tmp12, col2_sub_col6);
+  tmp12 = vsubq_s16(tmp12, tmp13);
+
+  int16x8_t tmp0 = vaddq_s16(tmp10, tmp13);
+  int16x8_t tmp3 = vsubq_s16(tmp10, tmp13);
+  int16x8_t tmp1 = vaddq_s16(tmp11, tmp12);
+  int16x8_t tmp2 = vsubq_s16(tmp11, tmp12);
+
+  /* Odd part */
+  int16x8_t z13 = vaddq_s16(col5, col3);
+  int16x8_t neg_z10 = vsubq_s16(col3, col5);
+  int16x8_t z11 = vaddq_s16(col1, col7);
+  int16x8_t z12 = vsubq_s16(col1, col7);
+
+  int16x8_t tmp7 = vaddq_s16(z11, z13);      /* phase 5 */
+  int16x8_t z11_sub_z13 = vsubq_s16(z11, z13);
+  tmp11 = vqdmulhq_lane_s16(z11_sub_z13, consts, 1);
+  tmp11 = vaddq_s16(tmp11, z11_sub_z13);
+
+  int16x8_t z10_add_z12 = vsubq_s16(z12, neg_z10);
+  int16x8_t z5 = vqdmulhq_lane_s16(z10_add_z12, consts, 2);
+  z5 = vaddq_s16(z5, z10_add_z12);
+  tmp10 = vqdmulhq_lane_s16(z12, consts, 0);
+  tmp10 = vaddq_s16(tmp10, z12);
+  tmp10 = vsubq_s16(tmp10, z5);
+  tmp12 = vqdmulhq_lane_s16(neg_z10, consts, 3);
+  tmp12 = vaddq_s16(tmp12, vaddq_s16(neg_z10, neg_z10));
+  tmp12 = vaddq_s16(tmp12, z5);
+
+  int16x8_t tmp6 = vsubq_s16(tmp12, tmp7);   /* phase 2 */
+  int16x8_t tmp5 = vsubq_s16(tmp11, tmp6);
+  int16x8_t tmp4 = vaddq_s16(tmp10, tmp5);
+
+  col0 = vaddq_s16(tmp0, tmp7);
+  col7 = vsubq_s16(tmp0, tmp7);
+  col1 = vaddq_s16(tmp1, tmp6);
+  col6 = vsubq_s16(tmp1, tmp6);
+  col2 = vaddq_s16(tmp2, tmp5);
+  col5 = vsubq_s16(tmp2, tmp5);
+  col4 = vaddq_s16(tmp3, tmp4);
+  col3 = vsubq_s16(tmp3, tmp4);
+
+  /* Scale down by a factor of 8, narrowing to 8-bit. */
+  int8x16_t cols_01_s8 = vcombine_s8(vqshrn_n_s16(col0, PASS1_BITS + 3),
+                                     vqshrn_n_s16(col1, PASS1_BITS + 3));
+  int8x16_t cols_45_s8 = vcombine_s8(vqshrn_n_s16(col4, PASS1_BITS + 3),
+                                     vqshrn_n_s16(col5, PASS1_BITS + 3));
+  int8x16_t cols_23_s8 = vcombine_s8(vqshrn_n_s16(col2, PASS1_BITS + 3),
+                                     vqshrn_n_s16(col3, PASS1_BITS + 3));
+  int8x16_t cols_67_s8 = vcombine_s8(vqshrn_n_s16(col6, PASS1_BITS + 3),
+                                     vqshrn_n_s16(col7, PASS1_BITS + 3));
+  /* Clamp to range [0-255]. */
+  uint8x16_t cols_01 =
+    vreinterpretq_u8_s8
+      (vaddq_s8(cols_01_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
+  uint8x16_t cols_45 =
+    vreinterpretq_u8_s8
+      (vaddq_s8(cols_45_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
+  uint8x16_t cols_23 =
+    vreinterpretq_u8_s8
+      (vaddq_s8(cols_23_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
+  uint8x16_t cols_67 =
+    vreinterpretq_u8_s8
+      (vaddq_s8(cols_67_s8, vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));
+
+  /* Transpose block to prepare for store. */
+  uint32x4x2_t cols_0415 = vzipq_u32(vreinterpretq_u32_u8(cols_01),
+                                     vreinterpretq_u32_u8(cols_45));
+  uint32x4x2_t cols_2637 = vzipq_u32(vreinterpretq_u32_u8(cols_23),
+                                     vreinterpretq_u32_u8(cols_67));
+
+  uint8x16x2_t cols_0145 = vtrnq_u8(vreinterpretq_u8_u32(cols_0415.val[0]),
+                                    vreinterpretq_u8_u32(cols_0415.val[1]));
+  uint8x16x2_t cols_2367 = vtrnq_u8(vreinterpretq_u8_u32(cols_2637.val[0]),
+                                    vreinterpretq_u8_u32(cols_2637.val[1]));
+  uint16x8x2_t rows_0426 = vtrnq_u16(vreinterpretq_u16_u8(cols_0145.val[0]),
+                                     vreinterpretq_u16_u8(cols_2367.val[0]));
+  uint16x8x2_t rows_1537 = vtrnq_u16(vreinterpretq_u16_u8(cols_0145.val[1]),
+                                     vreinterpretq_u16_u8(cols_2367.val[1]));
+
+  uint8x16_t rows_04 = vreinterpretq_u8_u16(rows_0426.val[0]);
+  uint8x16_t rows_15 = vreinterpretq_u8_u16(rows_1537.val[0]);
+  uint8x16_t rows_26 = vreinterpretq_u8_u16(rows_0426.val[1]);
+  uint8x16_t rows_37 = vreinterpretq_u8_u16(rows_1537.val[1]);
+
+  JSAMPROW outptr0 = output_buf[0] + output_col;
+  JSAMPROW outptr1 = output_buf[1] + output_col;
+  JSAMPROW outptr2 = output_buf[2] + output_col;
+  JSAMPROW outptr3 = output_buf[3] + output_col;
+  JSAMPROW outptr4 = output_buf[4] + output_col;
+  JSAMPROW outptr5 = output_buf[5] + output_col;
+  JSAMPROW outptr6 = output_buf[6] + output_col;
+  JSAMPROW outptr7 = output_buf[7] + output_col;
+
+  /* Store DCT block to memory. */
+  vst1q_lane_u64((uint64_t *)outptr0, vreinterpretq_u64_u8(rows_04), 0);
+  vst1q_lane_u64((uint64_t *)outptr1, vreinterpretq_u64_u8(rows_15), 0);
+  vst1q_lane_u64((uint64_t *)outptr2, vreinterpretq_u64_u8(rows_26), 0);
+  vst1q_lane_u64((uint64_t *)outptr3, vreinterpretq_u64_u8(rows_37), 0);
+  vst1q_lane_u64((uint64_t *)outptr4, vreinterpretq_u64_u8(rows_04), 1);
+  vst1q_lane_u64((uint64_t *)outptr5, vreinterpretq_u64_u8(rows_15), 1);
+  vst1q_lane_u64((uint64_t *)outptr6, vreinterpretq_u64_u8(rows_26), 1);
+  vst1q_lane_u64((uint64_t *)outptr7, vreinterpretq_u64_u8(rows_37), 1);
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jidctint-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jidctint-neon.c
new file mode 100644
index 0000000..043b652
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jidctint-neon.c
@@ -0,0 +1,802 @@
+/*
+ * jidctint-neon.c - accurate integer IDCT (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "jconfigint.h"
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+#include "neon-compat.h"
+
+#include <arm_neon.h>
+
+
+#define CONST_BITS  13
+#define PASS1_BITS  2
+
+#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
+#define DESCALE_P2  (CONST_BITS + PASS1_BITS + 3)
+
+/* The computation of the inverse DCT requires the use of constants known at
+ * compile time.  Scaled integer constants are used to avoid floating-point
+ * arithmetic:
+ *    0.298631336 =  2446 * 2^-13
+ *    0.390180644 =  3196 * 2^-13
+ *    0.541196100 =  4433 * 2^-13
+ *    0.765366865 =  6270 * 2^-13
+ *    0.899976223 =  7373 * 2^-13
+ *    1.175875602 =  9633 * 2^-13
+ *    1.501321110 = 12299 * 2^-13
+ *    1.847759065 = 15137 * 2^-13
+ *    1.961570560 = 16069 * 2^-13
+ *    2.053119869 = 16819 * 2^-13
+ *    2.562915447 = 20995 * 2^-13
+ *    3.072711026 = 25172 * 2^-13
+ */
+
+#define F_0_298  2446
+#define F_0_390  3196
+#define F_0_541  4433
+#define F_0_765  6270
+#define F_0_899  7373
+#define F_1_175  9633
+#define F_1_501  12299
+#define F_1_847  15137
+#define F_1_961  16069
+#define F_2_053  16819
+#define F_2_562  20995
+#define F_3_072  25172
+
+#define F_1_175_MINUS_1_961  (F_1_175 - F_1_961)
+#define F_1_175_MINUS_0_390  (F_1_175 - F_0_390)
+#define F_0_541_MINUS_1_847  (F_0_541 - F_1_847)
+#define F_3_072_MINUS_2_562  (F_3_072 - F_2_562)
+#define F_0_298_MINUS_0_899  (F_0_298 - F_0_899)
+#define F_1_501_MINUS_0_899  (F_1_501 - F_0_899)
+#define F_2_053_MINUS_2_562  (F_2_053 - F_2_562)
+#define F_0_541_PLUS_0_765   (F_0_541 + F_0_765)
+
+
+ALIGN(16) static const int16_t jsimd_idct_islow_neon_consts[] = {
+  F_0_899,             F_0_541,
+  F_2_562,             F_0_298_MINUS_0_899,
+  F_1_501_MINUS_0_899, F_2_053_MINUS_2_562,
+  F_0_541_PLUS_0_765,  F_1_175,
+  F_1_175_MINUS_0_390, F_0_541_MINUS_1_847,
+  F_3_072_MINUS_2_562, F_1_175_MINUS_1_961,
+  0, 0, 0, 0
+};
+
+
+/* Forward declaration of regular and sparse IDCT helper functions */
+
+static INLINE void jsimd_idct_islow_pass1_regular(int16x4_t row0,
+                                                  int16x4_t row1,
+                                                  int16x4_t row2,
+                                                  int16x4_t row3,
+                                                  int16x4_t row4,
+                                                  int16x4_t row5,
+                                                  int16x4_t row6,
+                                                  int16x4_t row7,
+                                                  int16x4_t quant_row0,
+                                                  int16x4_t quant_row1,
+                                                  int16x4_t quant_row2,
+                                                  int16x4_t quant_row3,
+                                                  int16x4_t quant_row4,
+                                                  int16x4_t quant_row5,
+                                                  int16x4_t quant_row6,
+                                                  int16x4_t quant_row7,
+                                                  int16_t *workspace_1,
+                                                  int16_t *workspace_2);
+
+static INLINE void jsimd_idct_islow_pass1_sparse(int16x4_t row0,
+                                                 int16x4_t row1,
+                                                 int16x4_t row2,
+                                                 int16x4_t row3,
+                                                 int16x4_t quant_row0,
+                                                 int16x4_t quant_row1,
+                                                 int16x4_t quant_row2,
+                                                 int16x4_t quant_row3,
+                                                 int16_t *workspace_1,
+                                                 int16_t *workspace_2);
+
+static INLINE void jsimd_idct_islow_pass2_regular(int16_t *workspace,
+                                                  JSAMPARRAY output_buf,
+                                                  JDIMENSION output_col,
+                                                  unsigned buf_offset);
+
+static INLINE void jsimd_idct_islow_pass2_sparse(int16_t *workspace,
+                                                 JSAMPARRAY output_buf,
+                                                 JDIMENSION output_col,
+                                                 unsigned buf_offset);
+
+
+/* Perform dequantization and inverse DCT on one block of coefficients.  For
+ * reference, the C implementation (jpeg_idct_slow()) can be found in
+ * jidctint.c.
+ *
+ * Optimization techniques used for fast data access:
+ *
+ * In each pass, the inverse DCT is computed for the left and right 4x8 halves
+ * of the DCT block.  This avoids spilling due to register pressure, and the
+ * increased granularity allows for an optimized calculation depending on the
+ * values of the DCT coefficients.  Between passes, intermediate data is stored
+ * in 4x8 workspace buffers.
+ *
+ * Transposing the 8x8 DCT block after each pass can be achieved by transposing
+ * each of the four 4x4 quadrants and swapping quadrants 1 and 2 (refer to the
+ * diagram below.)  Swapping quadrants is cheap, since the second pass can just
+ * swap the workspace buffer pointers.
+ *
+ *      +-------+-------+                   +-------+-------+
+ *      |       |       |                   |       |       |
+ *      |   0   |   1   |                   |   0   |   2   |
+ *      |       |       |    transpose      |       |       |
+ *      +-------+-------+     ------>       +-------+-------+
+ *      |       |       |                   |       |       |
+ *      |   2   |   3   |                   |   1   |   3   |
+ *      |       |       |                   |       |       |
+ *      +-------+-------+                   +-------+-------+
+ *
+ * Optimization techniques used to accelerate the inverse DCT calculation:
+ *
+ * In a DCT coefficient block, the coefficients are increasingly likely to be 0
+ * as you move diagonally from top left to bottom right.  If whole rows of
+ * coefficients are 0, then the inverse DCT calculation can be simplified.  On
+ * the first pass of the inverse DCT, we test for three special cases before
+ * defaulting to a full "regular" inverse DCT:
+ *
+ * 1) Coefficients in rows 4-7 are all zero.  In this case, we perform a
+ *    "sparse" simplified inverse DCT on rows 0-3.
+ * 2) AC coefficients (rows 1-7) are all zero.  In this case, the inverse DCT
+ *    result is equal to the dequantized DC coefficients.
+ * 3) AC and DC coefficients are all zero.  In this case, the inverse DCT
+ *    result is all zero.  For the left 4x8 half, this is handled identically
+ *    to Case 2 above.  For the right 4x8 half, we do no work and signal that
+ *    the "sparse" algorithm is required for the second pass.
+ *
+ * In the second pass, only a single special case is tested: whether the AC and
+ * DC coefficients were all zero in the right 4x8 block during the first pass
+ * (refer to Case 3 above.)  If this is the case, then a "sparse" variant of
+ * the second pass is performed for both the left and right halves of the DCT
+ * block.  (The transposition after the first pass means that the right 4x8
+ * block during the first pass becomes rows 4-7 during the second pass.)
+ */
+
+void jsimd_idct_islow_neon(void *dct_table, JCOEFPTR coef_block,
+                           JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  ISLOW_MULT_TYPE *quantptr = dct_table;
+
+  int16_t workspace_l[8 * DCTSIZE / 2];
+  int16_t workspace_r[8 * DCTSIZE / 2];
+
+  /* Compute IDCT first pass on left 4x8 coefficient block. */
+
+  /* Load DCT coefficients in left 4x8 block. */
+  int16x4_t row0 = vld1_s16(coef_block + 0 * DCTSIZE);
+  int16x4_t row1 = vld1_s16(coef_block + 1 * DCTSIZE);
+  int16x4_t row2 = vld1_s16(coef_block + 2 * DCTSIZE);
+  int16x4_t row3 = vld1_s16(coef_block + 3 * DCTSIZE);
+  int16x4_t row4 = vld1_s16(coef_block + 4 * DCTSIZE);
+  int16x4_t row5 = vld1_s16(coef_block + 5 * DCTSIZE);
+  int16x4_t row6 = vld1_s16(coef_block + 6 * DCTSIZE);
+  int16x4_t row7 = vld1_s16(coef_block + 7 * DCTSIZE);
+
+  /* Load quantization table for left 4x8 block. */
+  int16x4_t quant_row0 = vld1_s16(quantptr + 0 * DCTSIZE);
+  int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
+  int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
+  int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
+  int16x4_t quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE);
+  int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
+  int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
+  int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
+
+  /* Construct bitmap to test if DCT coefficients in left 4x8 block are 0. */
+  int16x4_t bitmap = vorr_s16(row7, row6);
+  bitmap = vorr_s16(bitmap, row5);
+  bitmap = vorr_s16(bitmap, row4);
+  int64_t bitmap_rows_4567 = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
+
+  if (bitmap_rows_4567 == 0) {
+    bitmap = vorr_s16(bitmap, row3);
+    bitmap = vorr_s16(bitmap, row2);
+    bitmap = vorr_s16(bitmap, row1);
+    int64_t left_ac_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
+
+    if (left_ac_bitmap == 0) {
+      int16x4_t dcval = vshl_n_s16(vmul_s16(row0, quant_row0), PASS1_BITS);
+      int16x4x4_t quadrant = { { dcval, dcval, dcval, dcval } };
+      /* Store 4x4 blocks to workspace, transposing in the process. */
+      vst4_s16(workspace_l, quadrant);
+      vst4_s16(workspace_r, quadrant);
+    } else {
+      jsimd_idct_islow_pass1_sparse(row0, row1, row2, row3, quant_row0,
+                                    quant_row1, quant_row2, quant_row3,
+                                    workspace_l, workspace_r);
+    }
+  } else {
+    jsimd_idct_islow_pass1_regular(row0, row1, row2, row3, row4, row5,
+                                   row6, row7, quant_row0, quant_row1,
+                                   quant_row2, quant_row3, quant_row4,
+                                   quant_row5, quant_row6, quant_row7,
+                                   workspace_l, workspace_r);
+  }
+
+  /* Compute IDCT first pass on right 4x8 coefficient block. */
+
+  /* Load DCT coefficients in right 4x8 block. */
+  row0 = vld1_s16(coef_block + 0 * DCTSIZE + 4);
+  row1 = vld1_s16(coef_block + 1 * DCTSIZE + 4);
+  row2 = vld1_s16(coef_block + 2 * DCTSIZE + 4);
+  row3 = vld1_s16(coef_block + 3 * DCTSIZE + 4);
+  row4 = vld1_s16(coef_block + 4 * DCTSIZE + 4);
+  row5 = vld1_s16(coef_block + 5 * DCTSIZE + 4);
+  row6 = vld1_s16(coef_block + 6 * DCTSIZE + 4);
+  row7 = vld1_s16(coef_block + 7 * DCTSIZE + 4);
+
+  /* Load quantization table for right 4x8 block. */
+  quant_row0 = vld1_s16(quantptr + 0 * DCTSIZE + 4);
+  quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
+  quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
+  quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
+  quant_row4 = vld1_s16(quantptr + 4 * DCTSIZE + 4);
+  quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
+  quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
+  quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
+
+  /* Construct bitmap to test if DCT coefficients in right 4x8 block are 0. */
+  bitmap = vorr_s16(row7, row6);
+  bitmap = vorr_s16(bitmap, row5);
+  bitmap = vorr_s16(bitmap, row4);
+  bitmap_rows_4567 = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
+  bitmap = vorr_s16(bitmap, row3);
+  bitmap = vorr_s16(bitmap, row2);
+  bitmap = vorr_s16(bitmap, row1);
+  int64_t right_ac_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
+
+  /* If this remains non-zero, a "regular" second pass will be performed. */
+  int64_t right_ac_dc_bitmap = 1;
+
+  if (right_ac_bitmap == 0) {
+    bitmap = vorr_s16(bitmap, row0);
+    right_ac_dc_bitmap = vget_lane_s64(vreinterpret_s64_s16(bitmap), 0);
+
+    if (right_ac_dc_bitmap != 0) {
+      int16x4_t dcval = vshl_n_s16(vmul_s16(row0, quant_row0), PASS1_BITS);
+      int16x4x4_t quadrant = { { dcval, dcval, dcval, dcval } };
+      /* Store 4x4 blocks to workspace, transposing in the process. */
+      vst4_s16(workspace_l + 4 * DCTSIZE / 2, quadrant);
+      vst4_s16(workspace_r + 4 * DCTSIZE / 2, quadrant);
+    }
+  } else {
+    if (bitmap_rows_4567 == 0) {
+      jsimd_idct_islow_pass1_sparse(row0, row1, row2, row3, quant_row0,
+                                    quant_row1, quant_row2, quant_row3,
+                                    workspace_l + 4 * DCTSIZE / 2,
+                                    workspace_r + 4 * DCTSIZE / 2);
+    } else {
+      jsimd_idct_islow_pass1_regular(row0, row1, row2, row3, row4, row5,
+                                     row6, row7, quant_row0, quant_row1,
+                                     quant_row2, quant_row3, quant_row4,
+                                     quant_row5, quant_row6, quant_row7,
+                                     workspace_l + 4 * DCTSIZE / 2,
+                                     workspace_r + 4 * DCTSIZE / 2);
+    }
+  }
+
+  /* Second pass: compute IDCT on rows in workspace. */
+
+  /* If all coefficients in right 4x8 block are 0, use "sparse" second pass. */
+  if (right_ac_dc_bitmap == 0) {
+    jsimd_idct_islow_pass2_sparse(workspace_l, output_buf, output_col, 0);
+    jsimd_idct_islow_pass2_sparse(workspace_r, output_buf, output_col, 4);
+  } else {
+    jsimd_idct_islow_pass2_regular(workspace_l, output_buf, output_col, 0);
+    jsimd_idct_islow_pass2_regular(workspace_r, output_buf, output_col, 4);
+  }
+}
+
+
+/* Perform dequantization and the first pass of the accurate inverse DCT on a
+ * 4x8 block of coefficients.  (To process the full 8x8 DCT block, this
+ * function-- or some other optimized variant-- needs to be called for both the
+ * left and right 4x8 blocks.)
+ *
+ * This "regular" version assumes that no optimization can be made to the IDCT
+ * calculation, since no useful set of AC coefficients is all 0.
+ *
+ * The original C implementation of the accurate IDCT (jpeg_idct_slow()) can be
+ * found in jidctint.c.  Algorithmic changes made here are documented inline.
+ */
+
+static INLINE void jsimd_idct_islow_pass1_regular(int16x4_t row0,
+                                                  int16x4_t row1,
+                                                  int16x4_t row2,
+                                                  int16x4_t row3,
+                                                  int16x4_t row4,
+                                                  int16x4_t row5,
+                                                  int16x4_t row6,
+                                                  int16x4_t row7,
+                                                  int16x4_t quant_row0,
+                                                  int16x4_t quant_row1,
+                                                  int16x4_t quant_row2,
+                                                  int16x4_t quant_row3,
+                                                  int16x4_t quant_row4,
+                                                  int16x4_t quant_row5,
+                                                  int16x4_t quant_row6,
+                                                  int16x4_t quant_row7,
+                                                  int16_t *workspace_1,
+                                                  int16_t *workspace_2)
+{
+  /* Load constants for IDCT computation. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
+#else
+  const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  /* Even part */
+  int16x4_t z2_s16 = vmul_s16(row2, quant_row2);
+  int16x4_t z3_s16 = vmul_s16(row6, quant_row6);
+
+  int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
+  int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
+  tmp2 = vmlal_lane_s16(tmp2, z3_s16, consts.val[2], 1);
+  tmp3 = vmlal_lane_s16(tmp3, z3_s16, consts.val[0], 1);
+
+  z2_s16 = vmul_s16(row0, quant_row0);
+  z3_s16 = vmul_s16(row4, quant_row4);
+
+  int32x4_t tmp0 = vshll_n_s16(vadd_s16(z2_s16, z3_s16), CONST_BITS);
+  int32x4_t tmp1 = vshll_n_s16(vsub_s16(z2_s16, z3_s16), CONST_BITS);
+
+  int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
+  int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
+  int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
+  int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
+
+  /* Odd part */
+  int16x4_t tmp0_s16 = vmul_s16(row7, quant_row7);
+  int16x4_t tmp1_s16 = vmul_s16(row5, quant_row5);
+  int16x4_t tmp2_s16 = vmul_s16(row3, quant_row3);
+  int16x4_t tmp3_s16 = vmul_s16(row1, quant_row1);
+
+  z3_s16 = vadd_s16(tmp0_s16, tmp2_s16);
+  int16x4_t z4_s16 = vadd_s16(tmp1_s16, tmp3_s16);
+
+  /* Implementation as per jpeg_idct_islow() in jidctint.c:
+   *   z5 = (z3 + z4) * 1.175875602;
+   *   z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
+   *   z3 += z5;  z4 += z5;
+   *
+   * This implementation:
+   *   z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
+   *   z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
+   */
+
+  int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
+  int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
+  z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
+  z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
+
+  /* Implementation as per jpeg_idct_islow() in jidctint.c:
+   *   z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
+   *   tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
+   *   tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
+   *   z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
+   *   tmp0 += z1 + z3;  tmp1 += z2 + z4;
+   *   tmp2 += z2 + z3;  tmp3 += z1 + z4;
+   *
+   * This implementation:
+   *   tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
+   *   tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
+   *   tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
+   *   tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
+   *   tmp0 += z3;  tmp1 += z4;
+   *   tmp2 += z3;  tmp3 += z4;
+   */
+
+  tmp0 = vmull_lane_s16(tmp0_s16, consts.val[0], 3);
+  tmp1 = vmull_lane_s16(tmp1_s16, consts.val[1], 1);
+  tmp2 = vmull_lane_s16(tmp2_s16, consts.val[2], 2);
+  tmp3 = vmull_lane_s16(tmp3_s16, consts.val[1], 0);
+
+  tmp0 = vmlsl_lane_s16(tmp0, tmp3_s16, consts.val[0], 0);
+  tmp1 = vmlsl_lane_s16(tmp1, tmp2_s16, consts.val[0], 2);
+  tmp2 = vmlsl_lane_s16(tmp2, tmp1_s16, consts.val[0], 2);
+  tmp3 = vmlsl_lane_s16(tmp3, tmp0_s16, consts.val[0], 0);
+
+  tmp0 = vaddq_s32(tmp0, z3);
+  tmp1 = vaddq_s32(tmp1, z4);
+  tmp2 = vaddq_s32(tmp2, z3);
+  tmp3 = vaddq_s32(tmp3, z4);
+
+  /* Final output stage: descale and narrow to 16-bit. */
+  int16x4x4_t rows_0123 = { {
+    vrshrn_n_s32(vaddq_s32(tmp10, tmp3), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp11, tmp2), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp12, tmp1), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp13, tmp0), DESCALE_P1)
+  } };
+  int16x4x4_t rows_4567 = { {
+    vrshrn_n_s32(vsubq_s32(tmp13, tmp0), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp12, tmp1), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp11, tmp2), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp10, tmp3), DESCALE_P1)
+  } };
+
+  /* Store 4x4 blocks to the intermediate workspace, ready for the second pass.
+   * (VST4 transposes the blocks.  We need to operate on rows in the next
+   * pass.)
+   */
+  vst4_s16(workspace_1, rows_0123);
+  vst4_s16(workspace_2, rows_4567);
+}
+
+
+/* Perform dequantization and the first pass of the accurate inverse DCT on a
+ * 4x8 block of coefficients.
+ *
+ * This "sparse" version assumes that the AC coefficients in rows 4-7 are all
+ * 0.  This simplifies the IDCT calculation, accelerating overall performance.
+ */
+
+static INLINE void jsimd_idct_islow_pass1_sparse(int16x4_t row0,
+                                                 int16x4_t row1,
+                                                 int16x4_t row2,
+                                                 int16x4_t row3,
+                                                 int16x4_t quant_row0,
+                                                 int16x4_t quant_row1,
+                                                 int16x4_t quant_row2,
+                                                 int16x4_t quant_row3,
+                                                 int16_t *workspace_1,
+                                                 int16_t *workspace_2)
+{
+  /* Load constants for IDCT computation. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
+#else
+  const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  /* Even part (z3 is all 0) */
+  int16x4_t z2_s16 = vmul_s16(row2, quant_row2);
+
+  int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
+  int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
+
+  z2_s16 = vmul_s16(row0, quant_row0);
+  int32x4_t tmp0 = vshll_n_s16(z2_s16, CONST_BITS);
+  int32x4_t tmp1 = vshll_n_s16(z2_s16, CONST_BITS);
+
+  int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
+  int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
+  int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
+  int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
+
+  /* Odd part (tmp0 and tmp1 are both all 0) */
+  int16x4_t tmp2_s16 = vmul_s16(row3, quant_row3);
+  int16x4_t tmp3_s16 = vmul_s16(row1, quant_row1);
+
+  int16x4_t z3_s16 = tmp2_s16;
+  int16x4_t z4_s16 = tmp3_s16;
+
+  int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
+  int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
+  z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
+  z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
+
+  tmp0 = vmlsl_lane_s16(z3, tmp3_s16, consts.val[0], 0);
+  tmp1 = vmlsl_lane_s16(z4, tmp2_s16, consts.val[0], 2);
+  tmp2 = vmlal_lane_s16(z3, tmp2_s16, consts.val[2], 2);
+  tmp3 = vmlal_lane_s16(z4, tmp3_s16, consts.val[1], 0);
+
+  /* Final output stage: descale and narrow to 16-bit. */
+  int16x4x4_t rows_0123 = { {
+    vrshrn_n_s32(vaddq_s32(tmp10, tmp3), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp11, tmp2), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp12, tmp1), DESCALE_P1),
+    vrshrn_n_s32(vaddq_s32(tmp13, tmp0), DESCALE_P1)
+  } };
+  int16x4x4_t rows_4567 = { {
+    vrshrn_n_s32(vsubq_s32(tmp13, tmp0), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp12, tmp1), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp11, tmp2), DESCALE_P1),
+    vrshrn_n_s32(vsubq_s32(tmp10, tmp3), DESCALE_P1)
+  } };
+
+  /* Store 4x4 blocks to the intermediate workspace, ready for the second pass.
+   * (VST4 transposes the blocks.  We need to operate on rows in the next
+   * pass.)
+   */
+  vst4_s16(workspace_1, rows_0123);
+  vst4_s16(workspace_2, rows_4567);
+}
+
+
+/* Perform the second pass of the accurate inverse DCT on a 4x8 block of
+ * coefficients.  (To process the full 8x8 DCT block, this function-- or some
+ * other optimized variant-- needs to be called for both the right and left 4x8
+ * blocks.)
+ *
+ * This "regular" version assumes that no optimization can be made to the IDCT
+ * calculation, since no useful set of coefficient values are all 0 after the
+ * first pass.
+ *
+ * Again, the original C implementation of the accurate IDCT (jpeg_idct_slow())
+ * can be found in jidctint.c.  Algorithmic changes made here are documented
+ * inline.
+ */
+
+static INLINE void jsimd_idct_islow_pass2_regular(int16_t *workspace,
+                                                  JSAMPARRAY output_buf,
+                                                  JDIMENSION output_col,
+                                                  unsigned buf_offset)
+{
+  /* Load constants for IDCT computation. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
+#else
+  const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  /* Even part */
+  int16x4_t z2_s16 = vld1_s16(workspace + 2 * DCTSIZE / 2);
+  int16x4_t z3_s16 = vld1_s16(workspace + 6 * DCTSIZE / 2);
+
+  int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
+  int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
+  tmp2 = vmlal_lane_s16(tmp2, z3_s16, consts.val[2], 1);
+  tmp3 = vmlal_lane_s16(tmp3, z3_s16, consts.val[0], 1);
+
+  z2_s16 = vld1_s16(workspace + 0 * DCTSIZE / 2);
+  z3_s16 = vld1_s16(workspace + 4 * DCTSIZE / 2);
+
+  int32x4_t tmp0 = vshll_n_s16(vadd_s16(z2_s16, z3_s16), CONST_BITS);
+  int32x4_t tmp1 = vshll_n_s16(vsub_s16(z2_s16, z3_s16), CONST_BITS);
+
+  int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
+  int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
+  int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
+  int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
+
+  /* Odd part */
+  int16x4_t tmp0_s16 = vld1_s16(workspace + 7 * DCTSIZE / 2);
+  int16x4_t tmp1_s16 = vld1_s16(workspace + 5 * DCTSIZE / 2);
+  int16x4_t tmp2_s16 = vld1_s16(workspace + 3 * DCTSIZE / 2);
+  int16x4_t tmp3_s16 = vld1_s16(workspace + 1 * DCTSIZE / 2);
+
+  z3_s16 = vadd_s16(tmp0_s16, tmp2_s16);
+  int16x4_t z4_s16 = vadd_s16(tmp1_s16, tmp3_s16);
+
+  /* Implementation as per jpeg_idct_islow() in jidctint.c:
+   *   z5 = (z3 + z4) * 1.175875602;
+   *   z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
+   *   z3 += z5;  z4 += z5;
+   *
+   * This implementation:
+   *   z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
+   *   z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
+   */
+
+  int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
+  int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
+  z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
+  z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
+
+  /* Implementation as per jpeg_idct_islow() in jidctint.c:
+   *   z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2;
+   *   tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869;
+   *   tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110;
+   *   z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
+   *   tmp0 += z1 + z3;  tmp1 += z2 + z4;
+   *   tmp2 += z2 + z3;  tmp3 += z1 + z4;
+   *
+   * This implementation:
+   *   tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223;
+   *   tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447;
+   *   tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447);
+   *   tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223);
+   *   tmp0 += z3;  tmp1 += z4;
+   *   tmp2 += z3;  tmp3 += z4;
+   */
+
+  tmp0 = vmull_lane_s16(tmp0_s16, consts.val[0], 3);
+  tmp1 = vmull_lane_s16(tmp1_s16, consts.val[1], 1);
+  tmp2 = vmull_lane_s16(tmp2_s16, consts.val[2], 2);
+  tmp3 = vmull_lane_s16(tmp3_s16, consts.val[1], 0);
+
+  tmp0 = vmlsl_lane_s16(tmp0, tmp3_s16, consts.val[0], 0);
+  tmp1 = vmlsl_lane_s16(tmp1, tmp2_s16, consts.val[0], 2);
+  tmp2 = vmlsl_lane_s16(tmp2, tmp1_s16, consts.val[0], 2);
+  tmp3 = vmlsl_lane_s16(tmp3, tmp0_s16, consts.val[0], 0);
+
+  tmp0 = vaddq_s32(tmp0, z3);
+  tmp1 = vaddq_s32(tmp1, z4);
+  tmp2 = vaddq_s32(tmp2, z3);
+  tmp3 = vaddq_s32(tmp3, z4);
+
+  /* Final output stage: descale and narrow to 16-bit. */
+  int16x8_t cols_02_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp3),
+                                       vaddhn_s32(tmp12, tmp1));
+  int16x8_t cols_13_s16 = vcombine_s16(vaddhn_s32(tmp11, tmp2),
+                                       vaddhn_s32(tmp13, tmp0));
+  int16x8_t cols_46_s16 = vcombine_s16(vsubhn_s32(tmp13, tmp0),
+                                       vsubhn_s32(tmp11, tmp2));
+  int16x8_t cols_57_s16 = vcombine_s16(vsubhn_s32(tmp12, tmp1),
+                                       vsubhn_s32(tmp10, tmp3));
+  /* Descale and narrow to 8-bit. */
+  int8x8_t cols_02_s8 = vqrshrn_n_s16(cols_02_s16, DESCALE_P2 - 16);
+  int8x8_t cols_13_s8 = vqrshrn_n_s16(cols_13_s16, DESCALE_P2 - 16);
+  int8x8_t cols_46_s8 = vqrshrn_n_s16(cols_46_s16, DESCALE_P2 - 16);
+  int8x8_t cols_57_s8 = vqrshrn_n_s16(cols_57_s16, DESCALE_P2 - 16);
+  /* Clamp to range [0-255]. */
+  uint8x8_t cols_02_u8 = vadd_u8(vreinterpret_u8_s8(cols_02_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_13_u8 = vadd_u8(vreinterpret_u8_s8(cols_13_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_46_u8 = vadd_u8(vreinterpret_u8_s8(cols_46_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_57_u8 = vadd_u8(vreinterpret_u8_s8(cols_57_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+
+  /* Transpose 4x8 block and store to memory.  (Zipping adjacent columns
+   * together allows us to store 16-bit elements.)
+   */
+  uint8x8x2_t cols_01_23 = vzip_u8(cols_02_u8, cols_13_u8);
+  uint8x8x2_t cols_45_67 = vzip_u8(cols_46_u8, cols_57_u8);
+  uint16x4x4_t cols_01_23_45_67 = { {
+    vreinterpret_u16_u8(cols_01_23.val[0]),
+    vreinterpret_u16_u8(cols_01_23.val[1]),
+    vreinterpret_u16_u8(cols_45_67.val[0]),
+    vreinterpret_u16_u8(cols_45_67.val[1])
+  } };
+
+  JSAMPROW outptr0 = output_buf[buf_offset + 0] + output_col;
+  JSAMPROW outptr1 = output_buf[buf_offset + 1] + output_col;
+  JSAMPROW outptr2 = output_buf[buf_offset + 2] + output_col;
+  JSAMPROW outptr3 = output_buf[buf_offset + 3] + output_col;
+  /* VST4 of 16-bit elements completes the transpose. */
+  vst4_lane_u16((uint16_t *)outptr0, cols_01_23_45_67, 0);
+  vst4_lane_u16((uint16_t *)outptr1, cols_01_23_45_67, 1);
+  vst4_lane_u16((uint16_t *)outptr2, cols_01_23_45_67, 2);
+  vst4_lane_u16((uint16_t *)outptr3, cols_01_23_45_67, 3);
+}
+
+
+/* Performs the second pass of the accurate inverse DCT on a 4x8 block
+ * of coefficients.
+ *
+ * This "sparse" version assumes that the coefficient values (after the first
+ * pass) in rows 4-7 are all 0.  This simplifies the IDCT calculation,
+ * accelerating overall performance.
+ */
+
+static INLINE void jsimd_idct_islow_pass2_sparse(int16_t *workspace,
+                                                 JSAMPARRAY output_buf,
+                                                 JDIMENSION output_col,
+                                                 unsigned buf_offset)
+{
+  /* Load constants for IDCT computation. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_islow_neon_consts);
+#else
+  const int16x4_t consts1 = vld1_s16(jsimd_idct_islow_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_idct_islow_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_idct_islow_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  /* Even part (z3 is all 0) */
+  int16x4_t z2_s16 = vld1_s16(workspace + 2 * DCTSIZE / 2);
+
+  int32x4_t tmp2 = vmull_lane_s16(z2_s16, consts.val[0], 1);
+  int32x4_t tmp3 = vmull_lane_s16(z2_s16, consts.val[1], 2);
+
+  z2_s16 = vld1_s16(workspace + 0 * DCTSIZE / 2);
+  int32x4_t tmp0 = vshll_n_s16(z2_s16, CONST_BITS);
+  int32x4_t tmp1 = vshll_n_s16(z2_s16, CONST_BITS);
+
+  int32x4_t tmp10 = vaddq_s32(tmp0, tmp3);
+  int32x4_t tmp13 = vsubq_s32(tmp0, tmp3);
+  int32x4_t tmp11 = vaddq_s32(tmp1, tmp2);
+  int32x4_t tmp12 = vsubq_s32(tmp1, tmp2);
+
+  /* Odd part (tmp0 and tmp1 are both all 0) */
+  int16x4_t tmp2_s16 = vld1_s16(workspace + 3 * DCTSIZE / 2);
+  int16x4_t tmp3_s16 = vld1_s16(workspace + 1 * DCTSIZE / 2);
+
+  int16x4_t z3_s16 = tmp2_s16;
+  int16x4_t z4_s16 = tmp3_s16;
+
+  int32x4_t z3 = vmull_lane_s16(z3_s16, consts.val[2], 3);
+  z3 = vmlal_lane_s16(z3, z4_s16, consts.val[1], 3);
+  int32x4_t z4 = vmull_lane_s16(z3_s16, consts.val[1], 3);
+  z4 = vmlal_lane_s16(z4, z4_s16, consts.val[2], 0);
+
+  tmp0 = vmlsl_lane_s16(z3, tmp3_s16, consts.val[0], 0);
+  tmp1 = vmlsl_lane_s16(z4, tmp2_s16, consts.val[0], 2);
+  tmp2 = vmlal_lane_s16(z3, tmp2_s16, consts.val[2], 2);
+  tmp3 = vmlal_lane_s16(z4, tmp3_s16, consts.val[1], 0);
+
+  /* Final output stage: descale and narrow to 16-bit. */
+  int16x8_t cols_02_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp3),
+                                       vaddhn_s32(tmp12, tmp1));
+  int16x8_t cols_13_s16 = vcombine_s16(vaddhn_s32(tmp11, tmp2),
+                                       vaddhn_s32(tmp13, tmp0));
+  int16x8_t cols_46_s16 = vcombine_s16(vsubhn_s32(tmp13, tmp0),
+                                       vsubhn_s32(tmp11, tmp2));
+  int16x8_t cols_57_s16 = vcombine_s16(vsubhn_s32(tmp12, tmp1),
+                                       vsubhn_s32(tmp10, tmp3));
+  /* Descale and narrow to 8-bit. */
+  int8x8_t cols_02_s8 = vqrshrn_n_s16(cols_02_s16, DESCALE_P2 - 16);
+  int8x8_t cols_13_s8 = vqrshrn_n_s16(cols_13_s16, DESCALE_P2 - 16);
+  int8x8_t cols_46_s8 = vqrshrn_n_s16(cols_46_s16, DESCALE_P2 - 16);
+  int8x8_t cols_57_s8 = vqrshrn_n_s16(cols_57_s16, DESCALE_P2 - 16);
+  /* Clamp to range [0-255]. */
+  uint8x8_t cols_02_u8 = vadd_u8(vreinterpret_u8_s8(cols_02_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_13_u8 = vadd_u8(vreinterpret_u8_s8(cols_13_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_46_u8 = vadd_u8(vreinterpret_u8_s8(cols_46_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+  uint8x8_t cols_57_u8 = vadd_u8(vreinterpret_u8_s8(cols_57_s8),
+                                 vdup_n_u8(CENTERJSAMPLE));
+
+  /* Transpose 4x8 block and store to memory.  (Zipping adjacent columns
+   * together allows us to store 16-bit elements.)
+   */
+  uint8x8x2_t cols_01_23 = vzip_u8(cols_02_u8, cols_13_u8);
+  uint8x8x2_t cols_45_67 = vzip_u8(cols_46_u8, cols_57_u8);
+  uint16x4x4_t cols_01_23_45_67 = { {
+    vreinterpret_u16_u8(cols_01_23.val[0]),
+    vreinterpret_u16_u8(cols_01_23.val[1]),
+    vreinterpret_u16_u8(cols_45_67.val[0]),
+    vreinterpret_u16_u8(cols_45_67.val[1])
+  } };
+
+  JSAMPROW outptr0 = output_buf[buf_offset + 0] + output_col;
+  JSAMPROW outptr1 = output_buf[buf_offset + 1] + output_col;
+  JSAMPROW outptr2 = output_buf[buf_offset + 2] + output_col;
+  JSAMPROW outptr3 = output_buf[buf_offset + 3] + output_col;
+  /* VST4 of 16-bit elements completes the transpose. */
+  vst4_lane_u16((uint16_t *)outptr0, cols_01_23_45_67, 0);
+  vst4_lane_u16((uint16_t *)outptr1, cols_01_23_45_67, 1);
+  vst4_lane_u16((uint16_t *)outptr2, cols_01_23_45_67, 2);
+  vst4_lane_u16((uint16_t *)outptr3, cols_01_23_45_67, 3);
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jidctred-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jidctred-neon.c
new file mode 100644
index 0000000..be9627e
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jidctred-neon.c
@@ -0,0 +1,486 @@
+/*
+ * jidctred-neon.c - reduced-size IDCT (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+#include "align.h"
+#include "neon-compat.h"
+
+#include <arm_neon.h>
+
+
+#define CONST_BITS  13
+#define PASS1_BITS  2
+
+#define F_0_211  1730
+#define F_0_509  4176
+#define F_0_601  4926
+#define F_0_720  5906
+#define F_0_765  6270
+#define F_0_850  6967
+#define F_0_899  7373
+#define F_1_061  8697
+#define F_1_272  10426
+#define F_1_451  11893
+#define F_1_847  15137
+#define F_2_172  17799
+#define F_2_562  20995
+#define F_3_624  29692
+
+
+/* jsimd_idct_2x2_neon() is an inverse DCT function that produces reduced-size
+ * 2x2 output from an 8x8 DCT block.  It uses the same calculations and
+ * produces exactly the same output as IJG's original jpeg_idct_2x2() function
+ * from jpeg-6b, which can be found in jidctred.c.
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.720959822 =  5906 * 2^-13
+ *    0.850430095 =  6967 * 2^-13
+ *    1.272758580 = 10426 * 2^-13
+ *    3.624509785 = 29692 * 2^-13
+ *
+ * See jidctred.c for further details of the 2x2 IDCT algorithm.  Where
+ * possible, the variable names and comments here in jsimd_idct_2x2_neon()
+ * match up with those in jpeg_idct_2x2().
+ */
+
+ALIGN(16) static const int16_t jsimd_idct_2x2_neon_consts[] = {
+  -F_0_720, F_0_850, -F_1_272, F_3_624
+};
+
+void jsimd_idct_2x2_neon(void *dct_table, JCOEFPTR coef_block,
+                         JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  ISLOW_MULT_TYPE *quantptr = dct_table;
+
+  /* Load DCT coefficients. */
+  int16x8_t row0 = vld1q_s16(coef_block + 0 * DCTSIZE);
+  int16x8_t row1 = vld1q_s16(coef_block + 1 * DCTSIZE);
+  int16x8_t row3 = vld1q_s16(coef_block + 3 * DCTSIZE);
+  int16x8_t row5 = vld1q_s16(coef_block + 5 * DCTSIZE);
+  int16x8_t row7 = vld1q_s16(coef_block + 7 * DCTSIZE);
+
+  /* Load quantization table values. */
+  int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
+  int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
+  int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
+  int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
+  int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
+
+  /* Dequantize DCT coefficients. */
+  row0 = vmulq_s16(row0, quant_row0);
+  row1 = vmulq_s16(row1, quant_row1);
+  row3 = vmulq_s16(row3, quant_row3);
+  row5 = vmulq_s16(row5, quant_row5);
+  row7 = vmulq_s16(row7, quant_row7);
+
+  /* Load IDCT conversion constants. */
+  const int16x4_t consts = vld1_s16(jsimd_idct_2x2_neon_consts);
+
+  /* Pass 1: process columns from input, put results in vectors row0 and
+   * row1.
+   */
+
+  /* Even part */
+  int32x4_t tmp10_l = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 2);
+  int32x4_t tmp10_h = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 2);
+
+  /* Odd part */
+  int32x4_t tmp0_l = vmull_lane_s16(vget_low_s16(row1), consts, 3);
+  tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row3), consts, 2);
+  tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row5), consts, 1);
+  tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(row7), consts, 0);
+  int32x4_t tmp0_h = vmull_lane_s16(vget_high_s16(row1), consts, 3);
+  tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row3), consts, 2);
+  tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row5), consts, 1);
+  tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(row7), consts, 0);
+
+  /* Final output stage: descale and narrow to 16-bit. */
+  row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10_l, tmp0_l), CONST_BITS),
+                      vrshrn_n_s32(vaddq_s32(tmp10_h, tmp0_h), CONST_BITS));
+  row1 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10_l, tmp0_l), CONST_BITS),
+                      vrshrn_n_s32(vsubq_s32(tmp10_h, tmp0_h), CONST_BITS));
+
+  /* Transpose two rows, ready for second pass. */
+  int16x8x2_t cols_0246_1357 = vtrnq_s16(row0, row1);
+  int16x8_t cols_0246 = cols_0246_1357.val[0];
+  int16x8_t cols_1357 = cols_0246_1357.val[1];
+  /* Duplicate columns such that each is accessible in its own vector. */
+  int32x4x2_t cols_1155_3377 = vtrnq_s32(vreinterpretq_s32_s16(cols_1357),
+                                         vreinterpretq_s32_s16(cols_1357));
+  int16x8_t cols_1155 = vreinterpretq_s16_s32(cols_1155_3377.val[0]);
+  int16x8_t cols_3377 = vreinterpretq_s16_s32(cols_1155_3377.val[1]);
+
+  /* Pass 2: process two rows, store to output array. */
+
+  /* Even part: we're only interested in col0; the top half of tmp10 is "don't
+   * care."
+   */
+  int32x4_t tmp10 = vshll_n_s16(vget_low_s16(cols_0246), CONST_BITS + 2);
+
+  /* Odd part: we're only interested in the bottom half of tmp0. */
+  int32x4_t tmp0 = vmull_lane_s16(vget_low_s16(cols_1155), consts, 3);
+  tmp0 = vmlal_lane_s16(tmp0, vget_low_s16(cols_3377), consts, 2);
+  tmp0 = vmlal_lane_s16(tmp0, vget_high_s16(cols_1155), consts, 1);
+  tmp0 = vmlal_lane_s16(tmp0, vget_high_s16(cols_3377), consts, 0);
+
+  /* Final output stage: descale and clamp to range [0-255]. */
+  int16x8_t output_s16 = vcombine_s16(vaddhn_s32(tmp10, tmp0),
+                                      vsubhn_s32(tmp10, tmp0));
+  output_s16 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_s16,
+                            CONST_BITS + PASS1_BITS + 3 + 2 - 16);
+  /* Narrow to 8-bit and convert to unsigned. */
+  uint8x8_t output_u8 = vqmovun_s16(output_s16);
+
+  /* Store 2x2 block to memory. */
+  vst1_lane_u8(output_buf[0] + output_col, output_u8, 0);
+  vst1_lane_u8(output_buf[1] + output_col, output_u8, 1);
+  vst1_lane_u8(output_buf[0] + output_col + 1, output_u8, 4);
+  vst1_lane_u8(output_buf[1] + output_col + 1, output_u8, 5);
+}
+
+
+/* jsimd_idct_4x4_neon() is an inverse DCT function that produces reduced-size
+ * 4x4 output from an 8x8 DCT block.  It uses the same calculations and
+ * produces exactly the same output as IJG's original jpeg_idct_4x4() function
+ * from jpeg-6b, which can be found in jidctred.c.
+ *
+ * Scaled integer constants are used to avoid floating-point arithmetic:
+ *    0.211164243 =  1730 * 2^-13
+ *    0.509795579 =  4176 * 2^-13
+ *    0.601344887 =  4926 * 2^-13
+ *    0.765366865 =  6270 * 2^-13
+ *    0.899976223 =  7373 * 2^-13
+ *    1.061594337 =  8697 * 2^-13
+ *    1.451774981 = 11893 * 2^-13
+ *    1.847759065 = 15137 * 2^-13
+ *    2.172734803 = 17799 * 2^-13
+ *    2.562915447 = 20995 * 2^-13
+ *
+ * See jidctred.c for further details of the 4x4 IDCT algorithm.  Where
+ * possible, the variable names and comments here in jsimd_idct_4x4_neon()
+ * match up with those in jpeg_idct_4x4().
+ */
+
+ALIGN(16) static const int16_t jsimd_idct_4x4_neon_consts[] = {
+  F_1_847, -F_0_765, -F_0_211,  F_1_451,
+ -F_2_172,  F_1_061, -F_0_509, -F_0_601,
+  F_0_899,  F_2_562,        0,        0
+};
+
+void jsimd_idct_4x4_neon(void *dct_table, JCOEFPTR coef_block,
+                         JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+  ISLOW_MULT_TYPE *quantptr = dct_table;
+
+  /* Load DCT coefficients. */
+  int16x8_t row0  = vld1q_s16(coef_block + 0 * DCTSIZE);
+  int16x8_t row1  = vld1q_s16(coef_block + 1 * DCTSIZE);
+  int16x8_t row2  = vld1q_s16(coef_block + 2 * DCTSIZE);
+  int16x8_t row3  = vld1q_s16(coef_block + 3 * DCTSIZE);
+  int16x8_t row5  = vld1q_s16(coef_block + 5 * DCTSIZE);
+  int16x8_t row6  = vld1q_s16(coef_block + 6 * DCTSIZE);
+  int16x8_t row7  = vld1q_s16(coef_block + 7 * DCTSIZE);
+
+  /* Load quantization table values for DC coefficients. */
+  int16x8_t quant_row0 = vld1q_s16(quantptr + 0 * DCTSIZE);
+  /* Dequantize DC coefficients. */
+  row0 = vmulq_s16(row0, quant_row0);
+
+  /* Construct bitmap to test if all AC coefficients are 0. */
+  int16x8_t bitmap = vorrq_s16(row1, row2);
+  bitmap = vorrq_s16(bitmap, row3);
+  bitmap = vorrq_s16(bitmap, row5);
+  bitmap = vorrq_s16(bitmap, row6);
+  bitmap = vorrq_s16(bitmap, row7);
+
+  int64_t left_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 0);
+  int64_t right_ac_bitmap = vgetq_lane_s64(vreinterpretq_s64_s16(bitmap), 1);
+
+  /* Load constants for IDCT computation. */
+#ifdef HAVE_VLD1_S16_X3
+  const int16x4x3_t consts = vld1_s16_x3(jsimd_idct_4x4_neon_consts);
+#else
+  /* GCC does not currently support the intrinsic vld1_<type>_x3(). */
+  const int16x4_t consts1 = vld1_s16(jsimd_idct_4x4_neon_consts);
+  const int16x4_t consts2 = vld1_s16(jsimd_idct_4x4_neon_consts + 4);
+  const int16x4_t consts3 = vld1_s16(jsimd_idct_4x4_neon_consts + 8);
+  const int16x4x3_t consts = { { consts1, consts2, consts3 } };
+#endif
+
+  if (left_ac_bitmap == 0 && right_ac_bitmap == 0) {
+    /* All AC coefficients are zero.
+     * Compute DC values and duplicate into row vectors 0, 1, 2, and 3.
+     */
+    int16x8_t dcval = vshlq_n_s16(row0, PASS1_BITS);
+    row0 = dcval;
+    row1 = dcval;
+    row2 = dcval;
+    row3 = dcval;
+  } else if (left_ac_bitmap == 0) {
+    /* AC coefficients are zero for columns 0, 1, 2, and 3.
+     * Compute DC values for these columns.
+     */
+    int16x4_t dcval = vshl_n_s16(vget_low_s16(row0), PASS1_BITS);
+
+    /* Commence regular IDCT computation for columns 4, 5, 6, and 7. */
+
+    /* Load quantization table. */
+    int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE + 4);
+    int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE + 4);
+    int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE + 4);
+    int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE + 4);
+    int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE + 4);
+    int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE + 4);
+
+    /* Even part */
+    int32x4_t tmp0 = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 1);
+
+    int16x4_t z2 = vmul_s16(vget_high_s16(row2), quant_row2);
+    int16x4_t z3 = vmul_s16(vget_high_s16(row6), quant_row6);
+
+    int32x4_t tmp2 = vmull_lane_s16(z2, consts.val[0], 0);
+    tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[0], 1);
+
+    int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
+    int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
+
+    /* Odd part */
+    int16x4_t z1 = vmul_s16(vget_high_s16(row7), quant_row7);
+    z2 = vmul_s16(vget_high_s16(row5), quant_row5);
+    z3 = vmul_s16(vget_high_s16(row3), quant_row3);
+    int16x4_t z4 = vmul_s16(vget_high_s16(row1), quant_row1);
+
+    tmp0 = vmull_lane_s16(z1, consts.val[0], 2);
+    tmp0 = vmlal_lane_s16(tmp0, z2, consts.val[0], 3);
+    tmp0 = vmlal_lane_s16(tmp0, z3, consts.val[1], 0);
+    tmp0 = vmlal_lane_s16(tmp0, z4, consts.val[1], 1);
+
+    tmp2 = vmull_lane_s16(z1, consts.val[1], 2);
+    tmp2 = vmlal_lane_s16(tmp2, z2, consts.val[1], 3);
+    tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[2], 0);
+    tmp2 = vmlal_lane_s16(tmp2, z4, consts.val[2], 1);
+
+    /* Final output stage: descale and narrow to 16-bit. */
+    row0 = vcombine_s16(dcval, vrshrn_n_s32(vaddq_s32(tmp10, tmp2),
+                                            CONST_BITS - PASS1_BITS + 1));
+    row3 = vcombine_s16(dcval, vrshrn_n_s32(vsubq_s32(tmp10, tmp2),
+                                            CONST_BITS - PASS1_BITS + 1));
+    row1 = vcombine_s16(dcval, vrshrn_n_s32(vaddq_s32(tmp12, tmp0),
+                                            CONST_BITS - PASS1_BITS + 1));
+    row2 = vcombine_s16(dcval, vrshrn_n_s32(vsubq_s32(tmp12, tmp0),
+                                            CONST_BITS - PASS1_BITS + 1));
+  } else if (right_ac_bitmap == 0) {
+    /* AC coefficients are zero for columns 4, 5, 6, and 7.
+     * Compute DC values for these columns.
+     */
+    int16x4_t dcval = vshl_n_s16(vget_high_s16(row0), PASS1_BITS);
+
+    /* Commence regular IDCT computation for columns 0, 1, 2, and 3. */
+
+    /* Load quantization table. */
+    int16x4_t quant_row1 = vld1_s16(quantptr + 1 * DCTSIZE);
+    int16x4_t quant_row2 = vld1_s16(quantptr + 2 * DCTSIZE);
+    int16x4_t quant_row3 = vld1_s16(quantptr + 3 * DCTSIZE);
+    int16x4_t quant_row5 = vld1_s16(quantptr + 5 * DCTSIZE);
+    int16x4_t quant_row6 = vld1_s16(quantptr + 6 * DCTSIZE);
+    int16x4_t quant_row7 = vld1_s16(quantptr + 7 * DCTSIZE);
+
+    /* Even part */
+    int32x4_t tmp0 = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 1);
+
+    int16x4_t z2 = vmul_s16(vget_low_s16(row2), quant_row2);
+    int16x4_t z3 = vmul_s16(vget_low_s16(row6), quant_row6);
+
+    int32x4_t tmp2 = vmull_lane_s16(z2, consts.val[0], 0);
+    tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[0], 1);
+
+    int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
+    int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
+
+    /* Odd part */
+    int16x4_t z1 = vmul_s16(vget_low_s16(row7), quant_row7);
+    z2 = vmul_s16(vget_low_s16(row5), quant_row5);
+    z3 = vmul_s16(vget_low_s16(row3), quant_row3);
+    int16x4_t z4 = vmul_s16(vget_low_s16(row1), quant_row1);
+
+    tmp0 = vmull_lane_s16(z1, consts.val[0], 2);
+    tmp0 = vmlal_lane_s16(tmp0, z2, consts.val[0], 3);
+    tmp0 = vmlal_lane_s16(tmp0, z3, consts.val[1], 0);
+    tmp0 = vmlal_lane_s16(tmp0, z4, consts.val[1], 1);
+
+    tmp2 = vmull_lane_s16(z1, consts.val[1], 2);
+    tmp2 = vmlal_lane_s16(tmp2, z2, consts.val[1], 3);
+    tmp2 = vmlal_lane_s16(tmp2, z3, consts.val[2], 0);
+    tmp2 = vmlal_lane_s16(tmp2, z4, consts.val[2], 1);
+
+    /* Final output stage: descale and narrow to 16-bit. */
+    row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10, tmp2),
+                                     CONST_BITS - PASS1_BITS + 1), dcval);
+    row3 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10, tmp2),
+                                     CONST_BITS - PASS1_BITS + 1), dcval);
+    row1 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp12, tmp0),
+                                     CONST_BITS - PASS1_BITS + 1), dcval);
+    row2 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp12, tmp0),
+                                     CONST_BITS - PASS1_BITS + 1), dcval);
+  } else {
+    /* All AC coefficients are non-zero; full IDCT calculation required. */
+    int16x8_t quant_row1 = vld1q_s16(quantptr + 1 * DCTSIZE);
+    int16x8_t quant_row2 = vld1q_s16(quantptr + 2 * DCTSIZE);
+    int16x8_t quant_row3 = vld1q_s16(quantptr + 3 * DCTSIZE);
+    int16x8_t quant_row5 = vld1q_s16(quantptr + 5 * DCTSIZE);
+    int16x8_t quant_row6 = vld1q_s16(quantptr + 6 * DCTSIZE);
+    int16x8_t quant_row7 = vld1q_s16(quantptr + 7 * DCTSIZE);
+
+    /* Even part */
+    int32x4_t tmp0_l = vshll_n_s16(vget_low_s16(row0), CONST_BITS + 1);
+    int32x4_t tmp0_h = vshll_n_s16(vget_high_s16(row0), CONST_BITS + 1);
+
+    int16x8_t z2 = vmulq_s16(row2, quant_row2);
+    int16x8_t z3 = vmulq_s16(row6, quant_row6);
+
+    int32x4_t tmp2_l = vmull_lane_s16(vget_low_s16(z2), consts.val[0], 0);
+    int32x4_t tmp2_h = vmull_lane_s16(vget_high_s16(z2), consts.val[0], 0);
+    tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z3), consts.val[0], 1);
+    tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z3), consts.val[0], 1);
+
+    int32x4_t tmp10_l = vaddq_s32(tmp0_l, tmp2_l);
+    int32x4_t tmp10_h = vaddq_s32(tmp0_h, tmp2_h);
+    int32x4_t tmp12_l = vsubq_s32(tmp0_l, tmp2_l);
+    int32x4_t tmp12_h = vsubq_s32(tmp0_h, tmp2_h);
+
+    /* Odd part */
+    int16x8_t z1 = vmulq_s16(row7, quant_row7);
+    z2 = vmulq_s16(row5, quant_row5);
+    z3 = vmulq_s16(row3, quant_row3);
+    int16x8_t z4 = vmulq_s16(row1, quant_row1);
+
+    tmp0_l = vmull_lane_s16(vget_low_s16(z1), consts.val[0], 2);
+    tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z2), consts.val[0], 3);
+    tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z3), consts.val[1], 0);
+    tmp0_l = vmlal_lane_s16(tmp0_l, vget_low_s16(z4), consts.val[1], 1);
+    tmp0_h = vmull_lane_s16(vget_high_s16(z1), consts.val[0], 2);
+    tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z2), consts.val[0], 3);
+    tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z3), consts.val[1], 0);
+    tmp0_h = vmlal_lane_s16(tmp0_h, vget_high_s16(z4), consts.val[1], 1);
+
+    tmp2_l = vmull_lane_s16(vget_low_s16(z1), consts.val[1], 2);
+    tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z2), consts.val[1], 3);
+    tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z3), consts.val[2], 0);
+    tmp2_l = vmlal_lane_s16(tmp2_l, vget_low_s16(z4), consts.val[2], 1);
+    tmp2_h = vmull_lane_s16(vget_high_s16(z1), consts.val[1], 2);
+    tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z2), consts.val[1], 3);
+    tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z3), consts.val[2], 0);
+    tmp2_h = vmlal_lane_s16(tmp2_h, vget_high_s16(z4), consts.val[2], 1);
+
+    /* Final output stage: descale and narrow to 16-bit. */
+    row0 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp10_l, tmp2_l),
+                                     CONST_BITS - PASS1_BITS + 1),
+                        vrshrn_n_s32(vaddq_s32(tmp10_h, tmp2_h),
+                                     CONST_BITS - PASS1_BITS + 1));
+    row3 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp10_l, tmp2_l),
+                                     CONST_BITS - PASS1_BITS + 1),
+                        vrshrn_n_s32(vsubq_s32(tmp10_h, tmp2_h),
+                                     CONST_BITS - PASS1_BITS + 1));
+    row1 = vcombine_s16(vrshrn_n_s32(vaddq_s32(tmp12_l, tmp0_l),
+                                     CONST_BITS - PASS1_BITS + 1),
+                        vrshrn_n_s32(vaddq_s32(tmp12_h, tmp0_h),
+                                     CONST_BITS - PASS1_BITS + 1));
+    row2 = vcombine_s16(vrshrn_n_s32(vsubq_s32(tmp12_l, tmp0_l),
+                                     CONST_BITS - PASS1_BITS + 1),
+                        vrshrn_n_s32(vsubq_s32(tmp12_h, tmp0_h),
+                                     CONST_BITS - PASS1_BITS + 1));
+  }
+
+  /* Transpose 8x4 block to perform IDCT on rows in second pass. */
+  int16x8x2_t row_01 = vtrnq_s16(row0, row1);
+  int16x8x2_t row_23 = vtrnq_s16(row2, row3);
+
+  int32x4x2_t cols_0426 = vtrnq_s32(vreinterpretq_s32_s16(row_01.val[0]),
+                                    vreinterpretq_s32_s16(row_23.val[0]));
+  int32x4x2_t cols_1537 = vtrnq_s32(vreinterpretq_s32_s16(row_01.val[1]),
+                                    vreinterpretq_s32_s16(row_23.val[1]));
+
+  int16x4_t col0 = vreinterpret_s16_s32(vget_low_s32(cols_0426.val[0]));
+  int16x4_t col1 = vreinterpret_s16_s32(vget_low_s32(cols_1537.val[0]));
+  int16x4_t col2 = vreinterpret_s16_s32(vget_low_s32(cols_0426.val[1]));
+  int16x4_t col3 = vreinterpret_s16_s32(vget_low_s32(cols_1537.val[1]));
+  int16x4_t col5 = vreinterpret_s16_s32(vget_high_s32(cols_1537.val[0]));
+  int16x4_t col6 = vreinterpret_s16_s32(vget_high_s32(cols_0426.val[1]));
+  int16x4_t col7 = vreinterpret_s16_s32(vget_high_s32(cols_1537.val[1]));
+
+  /* Commence second pass of IDCT. */
+
+  /* Even part */
+  int32x4_t tmp0 = vshll_n_s16(col0, CONST_BITS + 1);
+  int32x4_t tmp2 = vmull_lane_s16(col2, consts.val[0], 0);
+  tmp2 = vmlal_lane_s16(tmp2, col6, consts.val[0], 1);
+
+  int32x4_t tmp10 = vaddq_s32(tmp0, tmp2);
+  int32x4_t tmp12 = vsubq_s32(tmp0, tmp2);
+
+  /* Odd part */
+  tmp0 = vmull_lane_s16(col7, consts.val[0], 2);
+  tmp0 = vmlal_lane_s16(tmp0, col5, consts.val[0], 3);
+  tmp0 = vmlal_lane_s16(tmp0, col3, consts.val[1], 0);
+  tmp0 = vmlal_lane_s16(tmp0, col1, consts.val[1], 1);
+
+  tmp2 = vmull_lane_s16(col7, consts.val[1], 2);
+  tmp2 = vmlal_lane_s16(tmp2, col5, consts.val[1], 3);
+  tmp2 = vmlal_lane_s16(tmp2, col3, consts.val[2], 0);
+  tmp2 = vmlal_lane_s16(tmp2, col1, consts.val[2], 1);
+
+  /* Final output stage: descale and clamp to range [0-255]. */
+  int16x8_t output_cols_02 = vcombine_s16(vaddhn_s32(tmp10, tmp2),
+                                          vsubhn_s32(tmp12, tmp0));
+  int16x8_t output_cols_13 = vcombine_s16(vaddhn_s32(tmp12, tmp0),
+                                          vsubhn_s32(tmp10, tmp2));
+  output_cols_02 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_cols_02,
+                                CONST_BITS + PASS1_BITS + 3 + 1 - 16);
+  output_cols_13 = vrsraq_n_s16(vdupq_n_s16(CENTERJSAMPLE), output_cols_13,
+                                CONST_BITS + PASS1_BITS + 3 + 1 - 16);
+  /* Narrow to 8-bit and convert to unsigned while zipping 8-bit elements.
+   * An interleaving store completes the transpose.
+   */
+  uint8x8x2_t output_0123 = vzip_u8(vqmovun_s16(output_cols_02),
+                                    vqmovun_s16(output_cols_13));
+  uint16x4x2_t output_01_23 = { {
+    vreinterpret_u16_u8(output_0123.val[0]),
+    vreinterpret_u16_u8(output_0123.val[1])
+  } };
+
+  /* Store 4x4 block to memory. */
+  JSAMPROW outptr0 = output_buf[0] + output_col;
+  JSAMPROW outptr1 = output_buf[1] + output_col;
+  JSAMPROW outptr2 = output_buf[2] + output_col;
+  JSAMPROW outptr3 = output_buf[3] + output_col;
+  vst2_lane_u16((uint16_t *)outptr0, output_01_23, 0);
+  vst2_lane_u16((uint16_t *)outptr1, output_01_23, 1);
+  vst2_lane_u16((uint16_t *)outptr2, output_01_23, 2);
+  vst2_lane_u16((uint16_t *)outptr3, output_01_23, 3);
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jquanti-neon.c b/src/third_party/libjpeg-turbo/simd/arm/jquanti-neon.c
new file mode 100644
index 0000000..a7eb6f1
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/jquanti-neon.c
@@ -0,0 +1,190 @@
+/*
+ * jquanti-neon.c - sample data conversion and quantization (Arm Neon)
+ *
+ * Copyright (C) 2020, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#define JPEG_INTERNALS
+#include "../../jinclude.h"
+#include "../../jpeglib.h"
+#include "../../jsimd.h"
+#include "../../jdct.h"
+#include "../../jsimddct.h"
+#include "../jsimd.h"
+
+#include <arm_neon.h>
+
+
+/* After downsampling, the resulting sample values are in the range [0, 255],
+ * but the Discrete Cosine Transform (DCT) operates on values centered around
+ * 0.
+ *
+ * To prepare sample values for the DCT, load samples into a DCT workspace,
+ * subtracting CENTERJSAMPLE (128).  The samples, now in the range [-128, 127],
+ * are also widened from 8- to 16-bit.
+ *
+ * The equivalent scalar C function convsamp() can be found in jcdctmgr.c.
+ */
+
+void jsimd_convsamp_neon(JSAMPARRAY sample_data, JDIMENSION start_col,
+                         DCTELEM *workspace)
+{
+  uint8x8_t samp_row0 = vld1_u8(sample_data[0] + start_col);
+  uint8x8_t samp_row1 = vld1_u8(sample_data[1] + start_col);
+  uint8x8_t samp_row2 = vld1_u8(sample_data[2] + start_col);
+  uint8x8_t samp_row3 = vld1_u8(sample_data[3] + start_col);
+  uint8x8_t samp_row4 = vld1_u8(sample_data[4] + start_col);
+  uint8x8_t samp_row5 = vld1_u8(sample_data[5] + start_col);
+  uint8x8_t samp_row6 = vld1_u8(sample_data[6] + start_col);
+  uint8x8_t samp_row7 = vld1_u8(sample_data[7] + start_col);
+
+  int16x8_t row0 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row0, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row1 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row1, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row2 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row2, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row3 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row3, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row4 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row4, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row5 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row5, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row6 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row6, vdup_n_u8(CENTERJSAMPLE)));
+  int16x8_t row7 =
+    vreinterpretq_s16_u16(vsubl_u8(samp_row7, vdup_n_u8(CENTERJSAMPLE)));
+
+  vst1q_s16(workspace + 0 * DCTSIZE, row0);
+  vst1q_s16(workspace + 1 * DCTSIZE, row1);
+  vst1q_s16(workspace + 2 * DCTSIZE, row2);
+  vst1q_s16(workspace + 3 * DCTSIZE, row3);
+  vst1q_s16(workspace + 4 * DCTSIZE, row4);
+  vst1q_s16(workspace + 5 * DCTSIZE, row5);
+  vst1q_s16(workspace + 6 * DCTSIZE, row6);
+  vst1q_s16(workspace + 7 * DCTSIZE, row7);
+}
+
+
+/* After the DCT, the resulting array of coefficient values needs to be divided
+ * by an array of quantization values.
+ *
+ * To avoid a slow division operation, the DCT coefficients are multiplied by
+ * the (scaled) reciprocals of the quantization values and then right-shifted.
+ *
+ * The equivalent scalar C function quantize() can be found in jcdctmgr.c.
+ */
+
+void jsimd_quantize_neon(JCOEFPTR coef_block, DCTELEM *divisors,
+                         DCTELEM *workspace)
+{
+  JCOEFPTR out_ptr = coef_block;
+  UDCTELEM *recip_ptr = (UDCTELEM *)divisors;
+  UDCTELEM *corr_ptr = (UDCTELEM *)divisors + DCTSIZE2;
+  DCTELEM *shift_ptr = divisors + 3 * DCTSIZE2;
+  int i;
+
+  for (i = 0; i < DCTSIZE; i += DCTSIZE / 2) {
+    /* Load DCT coefficients. */
+    int16x8_t row0 = vld1q_s16(workspace + (i + 0) * DCTSIZE);
+    int16x8_t row1 = vld1q_s16(workspace + (i + 1) * DCTSIZE);
+    int16x8_t row2 = vld1q_s16(workspace + (i + 2) * DCTSIZE);
+    int16x8_t row3 = vld1q_s16(workspace + (i + 3) * DCTSIZE);
+    /* Load reciprocals of quantization values. */
+    uint16x8_t recip0 = vld1q_u16(recip_ptr + (i + 0) * DCTSIZE);
+    uint16x8_t recip1 = vld1q_u16(recip_ptr + (i + 1) * DCTSIZE);
+    uint16x8_t recip2 = vld1q_u16(recip_ptr + (i + 2) * DCTSIZE);
+    uint16x8_t recip3 = vld1q_u16(recip_ptr + (i + 3) * DCTSIZE);
+    uint16x8_t corr0 = vld1q_u16(corr_ptr + (i + 0) * DCTSIZE);
+    uint16x8_t corr1 = vld1q_u16(corr_ptr + (i + 1) * DCTSIZE);
+    uint16x8_t corr2 = vld1q_u16(corr_ptr + (i + 2) * DCTSIZE);
+    uint16x8_t corr3 = vld1q_u16(corr_ptr + (i + 3) * DCTSIZE);
+    int16x8_t shift0 = vld1q_s16(shift_ptr + (i + 0) * DCTSIZE);
+    int16x8_t shift1 = vld1q_s16(shift_ptr + (i + 1) * DCTSIZE);
+    int16x8_t shift2 = vld1q_s16(shift_ptr + (i + 2) * DCTSIZE);
+    int16x8_t shift3 = vld1q_s16(shift_ptr + (i + 3) * DCTSIZE);
+
+    /* Extract sign from coefficients. */
+    int16x8_t sign_row0 = vshrq_n_s16(row0, 15);
+    int16x8_t sign_row1 = vshrq_n_s16(row1, 15);
+    int16x8_t sign_row2 = vshrq_n_s16(row2, 15);
+    int16x8_t sign_row3 = vshrq_n_s16(row3, 15);
+    /* Get absolute value of DCT coefficients. */
+    uint16x8_t abs_row0 = vreinterpretq_u16_s16(vabsq_s16(row0));
+    uint16x8_t abs_row1 = vreinterpretq_u16_s16(vabsq_s16(row1));
+    uint16x8_t abs_row2 = vreinterpretq_u16_s16(vabsq_s16(row2));
+    uint16x8_t abs_row3 = vreinterpretq_u16_s16(vabsq_s16(row3));
+    /* Add correction. */
+    abs_row0 = vaddq_u16(abs_row0, corr0);
+    abs_row1 = vaddq_u16(abs_row1, corr1);
+    abs_row2 = vaddq_u16(abs_row2, corr2);
+    abs_row3 = vaddq_u16(abs_row3, corr3);
+
+    /* Multiply DCT coefficients by quantization reciprocals. */
+    int32x4_t row0_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row0),
+                                                       vget_low_u16(recip0)));
+    int32x4_t row0_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row0),
+                                                       vget_high_u16(recip0)));
+    int32x4_t row1_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row1),
+                                                       vget_low_u16(recip1)));
+    int32x4_t row1_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row1),
+                                                       vget_high_u16(recip1)));
+    int32x4_t row2_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row2),
+                                                       vget_low_u16(recip2)));
+    int32x4_t row2_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row2),
+                                                       vget_high_u16(recip2)));
+    int32x4_t row3_l = vreinterpretq_s32_u32(vmull_u16(vget_low_u16(abs_row3),
+                                                       vget_low_u16(recip3)));
+    int32x4_t row3_h = vreinterpretq_s32_u32(vmull_u16(vget_high_u16(abs_row3),
+                                                       vget_high_u16(recip3)));
+    /* Narrow back to 16-bit. */
+    row0 = vcombine_s16(vshrn_n_s32(row0_l, 16), vshrn_n_s32(row0_h, 16));
+    row1 = vcombine_s16(vshrn_n_s32(row1_l, 16), vshrn_n_s32(row1_h, 16));
+    row2 = vcombine_s16(vshrn_n_s32(row2_l, 16), vshrn_n_s32(row2_h, 16));
+    row3 = vcombine_s16(vshrn_n_s32(row3_l, 16), vshrn_n_s32(row3_h, 16));
+
+    /* Since VSHR only supports an immediate as its second argument, negate the
+     * shift value and shift left.
+     */
+    row0 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row0),
+                                           vnegq_s16(shift0)));
+    row1 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row1),
+                                           vnegq_s16(shift1)));
+    row2 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row2),
+                                           vnegq_s16(shift2)));
+    row3 = vreinterpretq_s16_u16(vshlq_u16(vreinterpretq_u16_s16(row3),
+                                           vnegq_s16(shift3)));
+
+    /* Restore sign to original product. */
+    row0 = veorq_s16(row0, sign_row0);
+    row0 = vsubq_s16(row0, sign_row0);
+    row1 = veorq_s16(row1, sign_row1);
+    row1 = vsubq_s16(row1, sign_row1);
+    row2 = veorq_s16(row2, sign_row2);
+    row2 = vsubq_s16(row2, sign_row2);
+    row3 = veorq_s16(row3, sign_row3);
+    row3 = vsubq_s16(row3, sign_row3);
+
+    /* Store quantized coefficients to memory. */
+    vst1q_s16(out_ptr + (i + 0) * DCTSIZE, row0);
+    vst1q_s16(out_ptr + (i + 1) * DCTSIZE, row1);
+    vst1q_s16(out_ptr + (i + 2) * DCTSIZE, row2);
+    vst1q_s16(out_ptr + (i + 3) * DCTSIZE, row3);
+  }
+}
diff --git a/src/third_party/libjpeg-turbo/simd/arm/jsimd_neon.S b/src/third_party/libjpeg-turbo/simd/arm/jsimd_neon.S
deleted file mode 100644
index af929fe..0000000
--- a/src/third_party/libjpeg-turbo/simd/arm/jsimd_neon.S
+++ /dev/null
@@ -1,2878 +0,0 @@
-/*
- * ARMv7 NEON optimizations for libjpeg-turbo
- *
- * Copyright (C) 2009-2011, Nokia Corporation and/or its subsidiary(-ies).
- *                          All Rights Reserved.
- * Author:  Siarhei Siamashka <siarhei.siamashka@nokia.com>
- * Copyright (C) 2014, Siarhei Siamashka.  All Rights Reserved.
- * Copyright (C) 2014, Linaro Limited.  All Rights Reserved.
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2015-2016, 2018, Matthieu Darbois.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack, "", %progbits  /* mark stack as non-executable */
-#endif
-
-.text
-.fpu neon
-.arch armv7a
-.object_arch armv4
-.arm
-.syntax unified
-
-
-#define RESPECT_STRICT_ALIGNMENT  1
-
-
-/*****************************************************************************/
-
-/* Supplementary macro for setting function attributes */
-.macro asm_function fname
-#ifdef __APPLE__
-    .private_extern _\fname
-    .globl _\fname
-_\fname:
-#else
-    .global \fname
-#ifdef __ELF__
-    .hidden \fname
-    .type \fname, %function
-#endif
-\fname:
-#endif
-.endm
-
-/* Transpose a block of 4x4 coefficients in four 64-bit registers */
-.macro transpose_4x4 x0, x1, x2, x3
-    vtrn.16         \x0, \x1
-    vtrn.16         \x2, \x3
-    vtrn.32         \x0, \x2
-    vtrn.32         \x1, \x3
-.endm
-
-
-#define CENTERJSAMPLE  128
-
-/*****************************************************************************/
-
-/*
- * Perform dequantization and inverse DCT on one block of coefficients.
- *
- * GLOBAL(void)
- * jsimd_idct_islow_neon(void *dct_table, JCOEFPTR coef_block,
- *                       JSAMPARRAY output_buf, JDIMENSION output_col)
- */
-
-#define FIX_0_298631336  (2446)
-#define FIX_0_390180644  (3196)
-#define FIX_0_541196100  (4433)
-#define FIX_0_765366865  (6270)
-#define FIX_0_899976223  (7373)
-#define FIX_1_175875602  (9633)
-#define FIX_1_501321110  (12299)
-#define FIX_1_847759065  (15137)
-#define FIX_1_961570560  (16069)
-#define FIX_2_053119869  (16819)
-#define FIX_2_562915447  (20995)
-#define FIX_3_072711026  (25172)
-
-#define FIX_1_175875602_MINUS_1_961570560  (FIX_1_175875602 - FIX_1_961570560)
-#define FIX_1_175875602_MINUS_0_390180644  (FIX_1_175875602 - FIX_0_390180644)
-#define FIX_0_541196100_MINUS_1_847759065  (FIX_0_541196100 - FIX_1_847759065)
-#define FIX_3_072711026_MINUS_2_562915447  (FIX_3_072711026 - FIX_2_562915447)
-#define FIX_0_298631336_MINUS_0_899976223  (FIX_0_298631336 - FIX_0_899976223)
-#define FIX_1_501321110_MINUS_0_899976223  (FIX_1_501321110 - FIX_0_899976223)
-#define FIX_2_053119869_MINUS_2_562915447  (FIX_2_053119869 - FIX_2_562915447)
-#define FIX_0_541196100_PLUS_0_765366865   (FIX_0_541196100 + FIX_0_765366865)
-
-/*
- * Reference SIMD-friendly 1-D ISLOW iDCT C implementation.
- * Uses some ideas from the comments in 'simd/jiss2int-64.asm'
- */
-#define REF_1D_IDCT(xrow0, xrow1, xrow2, xrow3, xrow4, xrow5, xrow6, xrow7) { \
-    DCTELEM row0, row1, row2, row3, row4, row5, row6, row7; \
-    JLONG   q1, q2, q3, q4, q5, q6, q7; \
-    JLONG   tmp11_plus_tmp2, tmp11_minus_tmp2; \
-    \
-    /* 1-D iDCT input data */ \
-    row0 = xrow0; \
-    row1 = xrow1; \
-    row2 = xrow2; \
-    row3 = xrow3; \
-    row4 = xrow4; \
-    row5 = xrow5; \
-    row6 = xrow6; \
-    row7 = xrow7; \
-    \
-    q5 = row7 + row3; \
-    q4 = row5 + row1; \
-    q6 = MULTIPLY(q5, FIX_1_175875602_MINUS_1_961570560) + \
-         MULTIPLY(q4, FIX_1_175875602); \
-    q7 = MULTIPLY(q5, FIX_1_175875602) + \
-         MULTIPLY(q4, FIX_1_175875602_MINUS_0_390180644); \
-    q2 = MULTIPLY(row2, FIX_0_541196100) + \
-         MULTIPLY(row6, FIX_0_541196100_MINUS_1_847759065); \
-    q4 = q6; \
-    q3 = ((JLONG)row0 - (JLONG)row4) << 13; \
-    q6 += MULTIPLY(row5, -FIX_2_562915447) + \
-          MULTIPLY(row3, FIX_3_072711026_MINUS_2_562915447); \
-    /* now we can use q1 (reloadable constants have been used up) */ \
-    q1 = q3 + q2; \
-    q4 += MULTIPLY(row7, FIX_0_298631336_MINUS_0_899976223) + \
-          MULTIPLY(row1, -FIX_0_899976223); \
-    q5 = q7; \
-    q1 = q1 + q6; \
-    q7 += MULTIPLY(row7, -FIX_0_899976223) + \
-          MULTIPLY(row1, FIX_1_501321110_MINUS_0_899976223); \
-    \
-    /* (tmp11 + tmp2) has been calculated (out_row1 before descale) */ \
-    tmp11_plus_tmp2 = q1; \
-    row1 = 0; \
-    \
-    q1 = q1 - q6; \
-    q5 += MULTIPLY(row5, FIX_2_053119869_MINUS_2_562915447) + \
-          MULTIPLY(row3, -FIX_2_562915447); \
-    q1 = q1 - q6; \
-    q6 = MULTIPLY(row2, FIX_0_541196100_PLUS_0_765366865) + \
-         MULTIPLY(row6, FIX_0_541196100); \
-    q3 = q3 - q2; \
-    \
-    /* (tmp11 - tmp2) has been calculated (out_row6 before descale) */ \
-    tmp11_minus_tmp2 = q1; \
-    \
-    q1 = ((JLONG)row0 + (JLONG)row4) << 13; \
-    q2 = q1 + q6; \
-    q1 = q1 - q6; \
-    \
-    /* pick up the results */ \
-    tmp0  = q4; \
-    tmp1  = q5; \
-    tmp2  = (tmp11_plus_tmp2 - tmp11_minus_tmp2) / 2; \
-    tmp3  = q7; \
-    tmp10 = q2; \
-    tmp11 = (tmp11_plus_tmp2 + tmp11_minus_tmp2) / 2; \
-    tmp12 = q3; \
-    tmp13 = q1; \
-}
-
-#define XFIX_0_899976223                    d0[0]
-#define XFIX_0_541196100                    d0[1]
-#define XFIX_2_562915447                    d0[2]
-#define XFIX_0_298631336_MINUS_0_899976223  d0[3]
-#define XFIX_1_501321110_MINUS_0_899976223  d1[0]
-#define XFIX_2_053119869_MINUS_2_562915447  d1[1]
-#define XFIX_0_541196100_PLUS_0_765366865   d1[2]
-#define XFIX_1_175875602                    d1[3]
-#define XFIX_1_175875602_MINUS_0_390180644  d2[0]
-#define XFIX_0_541196100_MINUS_1_847759065  d2[1]
-#define XFIX_3_072711026_MINUS_2_562915447  d2[2]
-#define XFIX_1_175875602_MINUS_1_961570560  d2[3]
-
-.balign 16
-jsimd_idct_islow_neon_consts:
-  .short FIX_0_899976223                    /* d0[0] */
-  .short FIX_0_541196100                    /* d0[1] */
-  .short FIX_2_562915447                    /* d0[2] */
-  .short FIX_0_298631336_MINUS_0_899976223  /* d0[3] */
-  .short FIX_1_501321110_MINUS_0_899976223  /* d1[0] */
-  .short FIX_2_053119869_MINUS_2_562915447  /* d1[1] */
-  .short FIX_0_541196100_PLUS_0_765366865   /* d1[2] */
-  .short FIX_1_175875602                    /* d1[3] */
-  /* reloadable constants */
-  .short FIX_1_175875602_MINUS_0_390180644  /* d2[0] */
-  .short FIX_0_541196100_MINUS_1_847759065  /* d2[1] */
-  .short FIX_3_072711026_MINUS_2_562915447  /* d2[2] */
-  .short FIX_1_175875602_MINUS_1_961570560  /* d2[3] */
-
-asm_function jsimd_idct_islow_neon
-
-    DCT_TABLE       .req r0
-    COEF_BLOCK      .req r1
-    OUTPUT_BUF      .req r2
-    OUTPUT_COL      .req r3
-    TMP1            .req r0
-    TMP2            .req r1
-    TMP3            .req r2
-    TMP4            .req ip
-
-    ROW0L           .req d16
-    ROW0R           .req d17
-    ROW1L           .req d18
-    ROW1R           .req d19
-    ROW2L           .req d20
-    ROW2R           .req d21
-    ROW3L           .req d22
-    ROW3R           .req d23
-    ROW4L           .req d24
-    ROW4R           .req d25
-    ROW5L           .req d26
-    ROW5R           .req d27
-    ROW6L           .req d28
-    ROW6R           .req d29
-    ROW7L           .req d30
-    ROW7R           .req d31
-
-    /* Load and dequantize coefficients into NEON registers
-     * with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17     ( q8  )
-     *   1 | d18     | d19     ( q9  )
-     *   2 | d20     | d21     ( q10 )
-     *   3 | d22     | d23     ( q11 )
-     *   4 | d24     | d25     ( q12 )
-     *   5 | d26     | d27     ( q13 )
-     *   6 | d28     | d29     ( q14 )
-     *   7 | d30     | d31     ( q15 )
-     */
-    adr             ip, jsimd_idct_islow_neon_consts
-    vld1.16         {d16, d17, d18, d19}, [COEF_BLOCK, :128]!
-    vld1.16         {d0, d1, d2, d3}, [DCT_TABLE, :128]!
-    vld1.16         {d20, d21, d22, d23}, [COEF_BLOCK, :128]!
-    vmul.s16        q8, q8, q0
-    vld1.16         {d4, d5, d6, d7}, [DCT_TABLE, :128]!
-    vmul.s16        q9, q9, q1
-    vld1.16         {d24, d25, d26, d27}, [COEF_BLOCK, :128]!
-    vmul.s16        q10, q10, q2
-    vld1.16         {d0, d1, d2, d3}, [DCT_TABLE, :128]!
-    vmul.s16        q11, q11, q3
-    vld1.16         {d28, d29, d30, d31}, [COEF_BLOCK, :128]
-    vmul.s16        q12, q12, q0
-    vld1.16         {d4, d5, d6, d7}, [DCT_TABLE, :128]!
-    vmul.s16        q14, q14, q2
-    vmul.s16        q13, q13, q1
-    vld1.16         {d0, d1, d2, d3}, [ip, :128]  /* load constants */
-    add             ip, ip, #16
-    vmul.s16        q15, q15, q3
-    vpush           {d8-d15}                      /* save NEON registers */
-    /* 1-D IDCT, pass 1, left 4x8 half */
-    vadd.s16        d4, ROW7L, ROW3L
-    vadd.s16        d5, ROW5L, ROW1L
-    vmull.s16       q6, d4, XFIX_1_175875602_MINUS_1_961570560
-    vmlal.s16       q6, d5, XFIX_1_175875602
-    vmull.s16       q7, d4, XFIX_1_175875602
-      /* Check for the zero coefficients in the right 4x8 half */
-      push            {r4, r5}
-    vmlal.s16       q7, d5, XFIX_1_175875602_MINUS_0_390180644
-    vsubl.s16       q3, ROW0L, ROW4L
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 1 * 8))]
-    vmull.s16       q2, ROW2L, XFIX_0_541196100
-    vmlal.s16       q2, ROW6L, XFIX_0_541196100_MINUS_1_847759065
-      orr             r0, r4, r5
-    vmov            q4, q6
-    vmlsl.s16       q6, ROW5L, XFIX_2_562915447
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 2 * 8))]
-    vmlal.s16       q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
-    vshl.s32        q3, q3, #13
-      orr             r0, r0, r4
-    vmlsl.s16       q4, ROW1L, XFIX_0_899976223
-      orr             r0, r0, r5
-    vadd.s32        q1, q3, q2
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 3 * 8))]
-    vmov            q5, q7
-    vadd.s32        q1, q1, q6
-      orr             r0, r0, r4
-    vmlsl.s16       q7, ROW7L, XFIX_0_899976223
-      orr             r0, r0, r5
-    vmlal.s16       q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
-    vrshrn.s32      ROW1L, q1, #11
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 4 * 8))]
-    vsub.s32        q1, q1, q6
-    vmlal.s16       q5, ROW5L, XFIX_2_053119869_MINUS_2_562915447
-      orr             r0, r0, r4
-    vmlsl.s16       q5, ROW3L, XFIX_2_562915447
-      orr             r0, r0, r5
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 5 * 8))]
-    vmlal.s16       q6, ROW6L, XFIX_0_541196100
-    vsub.s32        q3, q3, q2
-      orr             r0, r0, r4
-    vrshrn.s32      ROW6L, q1, #11
-      orr             r0, r0, r5
-    vadd.s32        q1, q3, q5
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 6 * 8))]
-    vsub.s32        q3, q3, q5
-    vaddl.s16       q5, ROW0L, ROW4L
-      orr             r0, r0, r4
-    vrshrn.s32      ROW2L, q1, #11
-      orr             r0, r0, r5
-    vrshrn.s32      ROW5L, q3, #11
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 7 * 8))]
-    vshl.s32        q5, q5, #13
-    vmlal.s16       q4, ROW7L, XFIX_0_298631336_MINUS_0_899976223
-      orr             r0, r0, r4
-    vadd.s32        q2, q5, q6
-      orrs            r0, r0, r5
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-      ldrd            r4, [COEF_BLOCK, #(-96 + 2 * (4 + 0 * 8))]
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-      orr             r0, r4, r5
-    vsub.s32        q3, q1, q4
-      pop             {r4, r5}
-    vrshrn.s32      ROW7L, q2, #11
-    vrshrn.s32      ROW3L, q5, #11
-    vrshrn.s32      ROW0L, q6, #11
-    vrshrn.s32      ROW4L, q3, #11
-
-      beq             3f  /* Go to do some special handling for the sparse
-                             right 4x8 half */
-
-    /* 1-D IDCT, pass 1, right 4x8 half */
-    vld1.s16        {d2}, [ip, :64]  /* reload constants */
-    vadd.s16        d10, ROW7R, ROW3R
-    vadd.s16        d8, ROW5R, ROW1R
-      /* Transpose left 4x8 half */
-      vtrn.16         ROW6L, ROW7L
-    vmull.s16       q6, d10, XFIX_1_175875602_MINUS_1_961570560
-    vmlal.s16       q6, d8, XFIX_1_175875602
-      vtrn.16         ROW2L, ROW3L
-    vmull.s16       q7, d10, XFIX_1_175875602
-    vmlal.s16       q7, d8, XFIX_1_175875602_MINUS_0_390180644
-      vtrn.16         ROW0L, ROW1L
-    vsubl.s16       q3, ROW0R, ROW4R
-    vmull.s16       q2, ROW2R, XFIX_0_541196100
-    vmlal.s16       q2, ROW6R, XFIX_0_541196100_MINUS_1_847759065
-      vtrn.16         ROW4L, ROW5L
-    vmov            q4, q6
-    vmlsl.s16       q6, ROW5R, XFIX_2_562915447
-    vmlal.s16       q6, ROW3R, XFIX_3_072711026_MINUS_2_562915447
-      vtrn.32         ROW1L, ROW3L
-    vshl.s32        q3, q3, #13
-    vmlsl.s16       q4, ROW1R, XFIX_0_899976223
-      vtrn.32         ROW4L, ROW6L
-    vadd.s32        q1, q3, q2
-    vmov            q5, q7
-    vadd.s32        q1, q1, q6
-      vtrn.32         ROW0L, ROW2L
-    vmlsl.s16       q7, ROW7R, XFIX_0_899976223
-    vmlal.s16       q7, ROW1R, XFIX_1_501321110_MINUS_0_899976223
-    vrshrn.s32      ROW1R, q1, #11
-      vtrn.32         ROW5L, ROW7L
-    vsub.s32        q1, q1, q6
-    vmlal.s16       q5, ROW5R, XFIX_2_053119869_MINUS_2_562915447
-    vmlsl.s16       q5, ROW3R, XFIX_2_562915447
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW2R, XFIX_0_541196100_PLUS_0_765366865
-    vmlal.s16       q6, ROW6R, XFIX_0_541196100
-    vsub.s32        q3, q3, q2
-    vrshrn.s32      ROW6R, q1, #11
-    vadd.s32        q1, q3, q5
-    vsub.s32        q3, q3, q5
-    vaddl.s16       q5, ROW0R, ROW4R
-    vrshrn.s32      ROW2R, q1, #11
-    vrshrn.s32      ROW5R, q3, #11
-    vshl.s32        q5, q5, #13
-    vmlal.s16       q4, ROW7R, XFIX_0_298631336_MINUS_0_899976223
-    vadd.s32        q2, q5, q6
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-    vsub.s32        q3, q1, q4
-    vrshrn.s32      ROW7R, q2, #11
-    vrshrn.s32      ROW3R, q5, #11
-    vrshrn.s32      ROW0R, q6, #11
-    vrshrn.s32      ROW4R, q3, #11
-    /* Transpose right 4x8 half */
-    vtrn.16         ROW6R, ROW7R
-    vtrn.16         ROW2R, ROW3R
-    vtrn.16         ROW0R, ROW1R
-    vtrn.16         ROW4R, ROW5R
-    vtrn.32         ROW1R, ROW3R
-    vtrn.32         ROW4R, ROW6R
-    vtrn.32         ROW0R, ROW2R
-    vtrn.32         ROW5R, ROW7R
-
-1:  /* 1-D IDCT, pass 2 (normal variant), left 4x8 half */
-    vld1.s16        {d2}, [ip, :64]               /* reload constants */
-    vmull.s16       q6, ROW1R, XFIX_1_175875602   /* ROW5L <-> ROW1R */
-    vmlal.s16       q6, ROW1L, XFIX_1_175875602
-    vmlal.s16       q6, ROW3R, XFIX_1_175875602_MINUS_1_961570560  /* ROW7L <-> ROW3R */
-    vmlal.s16       q6, ROW3L, XFIX_1_175875602_MINUS_1_961570560
-    vmull.s16       q7, ROW3R, XFIX_1_175875602   /* ROW7L <-> ROW3R */
-    vmlal.s16       q7, ROW3L, XFIX_1_175875602
-    vmlal.s16       q7, ROW1R, XFIX_1_175875602_MINUS_0_390180644  /* ROW5L <-> ROW1R */
-    vmlal.s16       q7, ROW1L, XFIX_1_175875602_MINUS_0_390180644
-    vsubl.s16       q3, ROW0L, ROW0R              /* ROW4L <-> ROW0R */
-    vmull.s16       q2, ROW2L, XFIX_0_541196100
-    vmlal.s16       q2, ROW2R, XFIX_0_541196100_MINUS_1_847759065  /* ROW6L <-> ROW2R */
-    vmov            q4, q6
-    vmlsl.s16       q6, ROW1R, XFIX_2_562915447   /* ROW5L <-> ROW1R */
-    vmlal.s16       q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
-    vshl.s32        q3, q3, #13
-    vmlsl.s16       q4, ROW1L, XFIX_0_899976223
-    vadd.s32        q1, q3, q2
-    vmov            q5, q7
-    vadd.s32        q1, q1, q6
-    vmlsl.s16       q7, ROW3R, XFIX_0_899976223   /* ROW7L <-> ROW3R */
-    vmlal.s16       q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
-    vshrn.s32       ROW1L, q1, #16
-    vsub.s32        q1, q1, q6
-    vmlal.s16       q5, ROW1R, XFIX_2_053119869_MINUS_2_562915447  /* ROW5L <-> ROW1R */
-    vmlsl.s16       q5, ROW3L, XFIX_2_562915447
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
-    vmlal.s16       q6, ROW2R, XFIX_0_541196100   /* ROW6L <-> ROW2R */
-    vsub.s32        q3, q3, q2
-    vshrn.s32       ROW2R, q1, #16                /* ROW6L <-> ROW2R */
-    vadd.s32        q1, q3, q5
-    vsub.s32        q3, q3, q5
-    vaddl.s16       q5, ROW0L, ROW0R              /* ROW4L <-> ROW0R */
-    vshrn.s32       ROW2L, q1, #16
-    vshrn.s32       ROW1R, q3, #16                /* ROW5L <-> ROW1R */
-    vshl.s32        q5, q5, #13
-    vmlal.s16       q4, ROW3R, XFIX_0_298631336_MINUS_0_899976223  /* ROW7L <-> ROW3R */
-    vadd.s32        q2, q5, q6
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-    vsub.s32        q3, q1, q4
-    vshrn.s32       ROW3R, q2, #16                /* ROW7L <-> ROW3R */
-    vshrn.s32       ROW3L, q5, #16
-    vshrn.s32       ROW0L, q6, #16
-    vshrn.s32       ROW0R, q3, #16                /* ROW4L <-> ROW0R */
-    /* 1-D IDCT, pass 2, right 4x8 half */
-    vld1.s16        {d2}, [ip, :64]               /* reload constants */
-    vmull.s16       q6, ROW5R, XFIX_1_175875602
-    vmlal.s16       q6, ROW5L, XFIX_1_175875602   /* ROW5L <-> ROW1R */
-    vmlal.s16       q6, ROW7R, XFIX_1_175875602_MINUS_1_961570560
-    vmlal.s16       q6, ROW7L, XFIX_1_175875602_MINUS_1_961570560  /* ROW7L <-> ROW3R */
-    vmull.s16       q7, ROW7R, XFIX_1_175875602
-    vmlal.s16       q7, ROW7L, XFIX_1_175875602   /* ROW7L <-> ROW3R */
-    vmlal.s16       q7, ROW5R, XFIX_1_175875602_MINUS_0_390180644
-    vmlal.s16       q7, ROW5L, XFIX_1_175875602_MINUS_0_390180644  /* ROW5L <-> ROW1R */
-    vsubl.s16       q3, ROW4L, ROW4R              /* ROW4L <-> ROW0R */
-    vmull.s16       q2, ROW6L, XFIX_0_541196100   /* ROW6L <-> ROW2R */
-    vmlal.s16       q2, ROW6R, XFIX_0_541196100_MINUS_1_847759065
-    vmov            q4, q6
-    vmlsl.s16       q6, ROW5R, XFIX_2_562915447
-    vmlal.s16       q6, ROW7L, XFIX_3_072711026_MINUS_2_562915447  /* ROW7L <-> ROW3R */
-    vshl.s32        q3, q3, #13
-    vmlsl.s16       q4, ROW5L, XFIX_0_899976223   /* ROW5L <-> ROW1R */
-    vadd.s32        q1, q3, q2
-    vmov            q5, q7
-    vadd.s32        q1, q1, q6
-    vmlsl.s16       q7, ROW7R, XFIX_0_899976223
-    vmlal.s16       q7, ROW5L, XFIX_1_501321110_MINUS_0_899976223  /* ROW5L <-> ROW1R */
-    vshrn.s32       ROW5L, q1, #16                /* ROW5L <-> ROW1R */
-    vsub.s32        q1, q1, q6
-    vmlal.s16       q5, ROW5R, XFIX_2_053119869_MINUS_2_562915447
-    vmlsl.s16       q5, ROW7L, XFIX_2_562915447   /* ROW7L <-> ROW3R */
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW6L, XFIX_0_541196100_PLUS_0_765366865  /* ROW6L <-> ROW2R */
-    vmlal.s16       q6, ROW6R, XFIX_0_541196100
-    vsub.s32        q3, q3, q2
-    vshrn.s32       ROW6R, q1, #16
-    vadd.s32        q1, q3, q5
-    vsub.s32        q3, q3, q5
-    vaddl.s16       q5, ROW4L, ROW4R              /* ROW4L <-> ROW0R */
-    vshrn.s32       ROW6L, q1, #16                /* ROW6L <-> ROW2R */
-    vshrn.s32       ROW5R, q3, #16
-    vshl.s32        q5, q5, #13
-    vmlal.s16       q4, ROW7R, XFIX_0_298631336_MINUS_0_899976223
-    vadd.s32        q2, q5, q6
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-    vsub.s32        q3, q1, q4
-    vshrn.s32       ROW7R, q2, #16
-    vshrn.s32       ROW7L, q5, #16                /* ROW7L <-> ROW3R */
-    vshrn.s32       ROW4L, q6, #16                /* ROW4L <-> ROW0R */
-    vshrn.s32       ROW4R, q3, #16
-
-2:  /* Descale to 8-bit and range limit */
-    vqrshrn.s16     d16, q8, #2
-    vqrshrn.s16     d17, q9, #2
-    vqrshrn.s16     d18, q10, #2
-    vqrshrn.s16     d19, q11, #2
-    vpop            {d8-d15}                      /* restore NEON registers */
-    vqrshrn.s16     d20, q12, #2
-      /* Transpose the final 8-bit samples and do signed->unsigned conversion */
-      vtrn.16         q8, q9
-    vqrshrn.s16     d21, q13, #2
-    vqrshrn.s16     d22, q14, #2
-      vmov.u8         q0, #(CENTERJSAMPLE)
-    vqrshrn.s16     d23, q15, #2
-      vtrn.8          d16, d17
-      vtrn.8          d18, d19
-      vadd.u8         q8, q8, q0
-      vadd.u8         q9, q9, q0
-      vtrn.16         q10, q11
-        /* Store results to the output buffer */
-        ldmia           OUTPUT_BUF!, {TMP1, TMP2}
-        add             TMP1, TMP1, OUTPUT_COL
-        add             TMP2, TMP2, OUTPUT_COL
-        vst1.8          {d16}, [TMP1]
-      vtrn.8          d20, d21
-        vst1.8          {d17}, [TMP2]
-        ldmia           OUTPUT_BUF!, {TMP1, TMP2}
-        add             TMP1, TMP1, OUTPUT_COL
-        add             TMP2, TMP2, OUTPUT_COL
-        vst1.8          {d18}, [TMP1]
-      vadd.u8         q10, q10, q0
-        vst1.8          {d19}, [TMP2]
-        ldmia           OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
-        add             TMP1, TMP1, OUTPUT_COL
-        add             TMP2, TMP2, OUTPUT_COL
-        add             TMP3, TMP3, OUTPUT_COL
-        add             TMP4, TMP4, OUTPUT_COL
-      vtrn.8          d22, d23
-        vst1.8          {d20}, [TMP1]
-      vadd.u8         q11, q11, q0
-        vst1.8          {d21}, [TMP2]
-        vst1.8          {d22}, [TMP3]
-        vst1.8          {d23}, [TMP4]
-    bx              lr
-
-3:  /* Left 4x8 half is done, right 4x8 half contains mostly zeros */
-
-    /* Transpose left 4x8 half */
-    vtrn.16         ROW6L, ROW7L
-    vtrn.16         ROW2L, ROW3L
-    vtrn.16         ROW0L, ROW1L
-    vtrn.16         ROW4L, ROW5L
-    vshl.s16        ROW0R, ROW0R, #2  /* PASS1_BITS */
-    vtrn.32         ROW1L, ROW3L
-    vtrn.32         ROW4L, ROW6L
-    vtrn.32         ROW0L, ROW2L
-    vtrn.32         ROW5L, ROW7L
-
-    cmp             r0, #0
-    beq             4f  /* Right 4x8 half has all zeros, go to 'sparse' second
-                           pass */
-
-    /* Only row 0 is non-zero for the right 4x8 half  */
-    vdup.s16        ROW1R, ROW0R[1]
-    vdup.s16        ROW2R, ROW0R[2]
-    vdup.s16        ROW3R, ROW0R[3]
-    vdup.s16        ROW4R, ROW0R[0]
-    vdup.s16        ROW5R, ROW0R[1]
-    vdup.s16        ROW6R, ROW0R[2]
-    vdup.s16        ROW7R, ROW0R[3]
-    vdup.s16        ROW0R, ROW0R[0]
-    b               1b  /* Go to 'normal' second pass */
-
-4:  /* 1-D IDCT, pass 2 (sparse variant with zero rows 4-7), left 4x8 half */
-    vld1.s16        {d2}, [ip, :64]               /* reload constants */
-    vmull.s16       q6, ROW1L, XFIX_1_175875602
-    vmlal.s16       q6, ROW3L, XFIX_1_175875602_MINUS_1_961570560
-    vmull.s16       q7, ROW3L, XFIX_1_175875602
-    vmlal.s16       q7, ROW1L, XFIX_1_175875602_MINUS_0_390180644
-    vmull.s16       q2, ROW2L, XFIX_0_541196100
-    vshll.s16       q3, ROW0L, #13
-    vmov            q4, q6
-    vmlal.s16       q6, ROW3L, XFIX_3_072711026_MINUS_2_562915447
-    vmlsl.s16       q4, ROW1L, XFIX_0_899976223
-    vadd.s32        q1, q3, q2
-    vmov            q5, q7
-    vmlal.s16       q7, ROW1L, XFIX_1_501321110_MINUS_0_899976223
-    vadd.s32        q1, q1, q6
-    vadd.s32        q6, q6, q6
-    vmlsl.s16       q5, ROW3L, XFIX_2_562915447
-    vshrn.s32       ROW1L, q1, #16
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW2L, XFIX_0_541196100_PLUS_0_765366865
-    vsub.s32        q3, q3, q2
-    vshrn.s32       ROW2R, q1, #16                /* ROW6L <-> ROW2R */
-    vadd.s32        q1, q3, q5
-    vsub.s32        q3, q3, q5
-    vshll.s16       q5, ROW0L, #13
-    vshrn.s32       ROW2L, q1, #16
-    vshrn.s32       ROW1R, q3, #16                /* ROW5L <-> ROW1R */
-    vadd.s32        q2, q5, q6
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-    vsub.s32        q3, q1, q4
-    vshrn.s32       ROW3R, q2, #16                /* ROW7L <-> ROW3R */
-    vshrn.s32       ROW3L, q5, #16
-    vshrn.s32       ROW0L, q6, #16
-    vshrn.s32       ROW0R, q3, #16                /* ROW4L <-> ROW0R */
-    /* 1-D IDCT, pass 2 (sparse variant with zero rows 4-7), right 4x8 half */
-    vld1.s16        {d2}, [ip, :64]               /* reload constants */
-    vmull.s16       q6, ROW5L, XFIX_1_175875602
-    vmlal.s16       q6, ROW7L, XFIX_1_175875602_MINUS_1_961570560
-    vmull.s16       q7, ROW7L, XFIX_1_175875602
-    vmlal.s16       q7, ROW5L, XFIX_1_175875602_MINUS_0_390180644
-    vmull.s16       q2, ROW6L, XFIX_0_541196100
-    vshll.s16       q3, ROW4L, #13
-    vmov            q4, q6
-    vmlal.s16       q6, ROW7L, XFIX_3_072711026_MINUS_2_562915447
-    vmlsl.s16       q4, ROW5L, XFIX_0_899976223
-    vadd.s32        q1, q3, q2
-    vmov            q5, q7
-    vmlal.s16       q7, ROW5L, XFIX_1_501321110_MINUS_0_899976223
-    vadd.s32        q1, q1, q6
-    vadd.s32        q6, q6, q6
-    vmlsl.s16       q5, ROW7L, XFIX_2_562915447
-    vshrn.s32       ROW5L, q1, #16                /* ROW5L <-> ROW1R */
-    vsub.s32        q1, q1, q6
-    vmull.s16       q6, ROW6L, XFIX_0_541196100_PLUS_0_765366865
-    vsub.s32        q3, q3, q2
-    vshrn.s32       ROW6R, q1, #16
-    vadd.s32        q1, q3, q5
-    vsub.s32        q3, q3, q5
-    vshll.s16       q5, ROW4L, #13
-    vshrn.s32       ROW6L, q1, #16                /* ROW6L <-> ROW2R */
-    vshrn.s32       ROW5R, q3, #16
-    vadd.s32        q2, q5, q6
-    vsub.s32        q1, q5, q6
-    vadd.s32        q6, q2, q7
-    vsub.s32        q2, q2, q7
-    vadd.s32        q5, q1, q4
-    vsub.s32        q3, q1, q4
-    vshrn.s32       ROW7R, q2, #16
-    vshrn.s32       ROW7L, q5, #16                /* ROW7L <-> ROW3R */
-    vshrn.s32       ROW4L, q6, #16                /* ROW4L <-> ROW0R */
-    vshrn.s32       ROW4R, q3, #16
-    b               2b                            /* Go to epilogue */
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-
-    .unreq          ROW0L
-    .unreq          ROW0R
-    .unreq          ROW1L
-    .unreq          ROW1R
-    .unreq          ROW2L
-    .unreq          ROW2R
-    .unreq          ROW3L
-    .unreq          ROW3R
-    .unreq          ROW4L
-    .unreq          ROW4R
-    .unreq          ROW5L
-    .unreq          ROW5R
-    .unreq          ROW6L
-    .unreq          ROW6R
-    .unreq          ROW7L
-    .unreq          ROW7R
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_ifast_neon
- *
- * This function contains a fast, not so accurate integer implementation of
- * the inverse DCT (Discrete Cosine Transform). It uses the same calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_ifast'
- * function from jidctfst.c
- *
- * Normally 1-D AAN DCT needs 5 multiplications and 29 additions.
- * But in ARM NEON case some extra additions are required because VQDMULH
- * instruction can't handle the constants larger than 1. So the expressions
- * like "x * 1.082392200" have to be converted to "x * 0.082392200 + x",
- * which introduces an extra addition. Overall, there are 6 extra additions
- * per 1-D IDCT pass, totalling to 5 VQDMULH and 35 VADD/VSUB instructions.
- */
-
-#define XFIX_1_082392200  d0[0]
-#define XFIX_1_414213562  d0[1]
-#define XFIX_1_847759065  d0[2]
-#define XFIX_2_613125930  d0[3]
-
-.balign 16
-jsimd_idct_ifast_neon_consts:
-  .short (277 * 128 - 256 * 128)  /* XFIX_1_082392200 */
-  .short (362 * 128 - 256 * 128)  /* XFIX_1_414213562 */
-  .short (473 * 128 - 256 * 128)  /* XFIX_1_847759065 */
-  .short (669 * 128 - 512 * 128)  /* XFIX_2_613125930 */
-
-asm_function jsimd_idct_ifast_neon
-
-    DCT_TABLE       .req r0
-    COEF_BLOCK      .req r1
-    OUTPUT_BUF      .req r2
-    OUTPUT_COL      .req r3
-    TMP1            .req r0
-    TMP2            .req r1
-    TMP3            .req r2
-    TMP4            .req ip
-
-    /* Load and dequantize coefficients into NEON registers
-     * with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17     ( q8  )
-     *   1 | d18     | d19     ( q9  )
-     *   2 | d20     | d21     ( q10 )
-     *   3 | d22     | d23     ( q11 )
-     *   4 | d24     | d25     ( q12 )
-     *   5 | d26     | d27     ( q13 )
-     *   6 | d28     | d29     ( q14 )
-     *   7 | d30     | d31     ( q15 )
-     */
-    adr             ip, jsimd_idct_ifast_neon_consts
-    vld1.16         {d16, d17, d18, d19}, [COEF_BLOCK, :128]!
-    vld1.16         {d0, d1, d2, d3}, [DCT_TABLE, :128]!
-    vld1.16         {d20, d21, d22, d23}, [COEF_BLOCK, :128]!
-    vmul.s16        q8, q8, q0
-    vld1.16         {d4, d5, d6, d7}, [DCT_TABLE, :128]!
-    vmul.s16        q9, q9, q1
-    vld1.16         {d24, d25, d26, d27}, [COEF_BLOCK, :128]!
-    vmul.s16        q10, q10, q2
-    vld1.16         {d0, d1, d2, d3}, [DCT_TABLE, :128]!
-    vmul.s16        q11, q11, q3
-    vld1.16         {d28, d29, d30, d31}, [COEF_BLOCK, :128]
-    vmul.s16        q12, q12, q0
-    vld1.16         {d4, d5, d6, d7}, [DCT_TABLE, :128]!
-    vmul.s16        q14, q14, q2
-    vmul.s16        q13, q13, q1
-    vld1.16         {d0}, [ip, :64]  /* load constants */
-    vmul.s16        q15, q15, q3
-    vpush           {d8-d13}         /* save NEON registers */
-    /* 1-D IDCT, pass 1 */
-    vsub.s16        q2, q10, q14
-    vadd.s16        q14, q10, q14
-    vsub.s16        q1, q11, q13
-    vadd.s16        q13, q11, q13
-    vsub.s16        q5, q9, q15
-    vadd.s16        q15, q9, q15
-    vqdmulh.s16     q4, q2, XFIX_1_414213562
-    vqdmulh.s16     q6, q1, XFIX_2_613125930
-    vadd.s16        q3, q1, q1
-    vsub.s16        q1, q5, q1
-    vadd.s16        q10, q2, q4
-    vqdmulh.s16     q4, q1, XFIX_1_847759065
-    vsub.s16        q2, q15, q13
-    vadd.s16        q3, q3, q6
-    vqdmulh.s16     q6, q2, XFIX_1_414213562
-    vadd.s16        q1, q1, q4
-    vqdmulh.s16     q4, q5, XFIX_1_082392200
-    vsub.s16        q10, q10, q14
-    vadd.s16        q2, q2, q6
-    vsub.s16        q6, q8, q12
-    vadd.s16        q12, q8, q12
-    vadd.s16        q9, q5, q4
-    vadd.s16        q5, q6, q10
-    vsub.s16        q10, q6, q10
-    vadd.s16        q6, q15, q13
-    vadd.s16        q8, q12, q14
-    vsub.s16        q3, q6, q3
-    vsub.s16        q12, q12, q14
-    vsub.s16        q3, q3, q1
-    vsub.s16        q1, q9, q1
-    vadd.s16        q2, q3, q2
-    vsub.s16        q15, q8, q6
-    vadd.s16        q1, q1, q2
-    vadd.s16        q8, q8, q6
-    vadd.s16        q14, q5, q3
-    vsub.s16        q9, q5, q3
-    vsub.s16        q13, q10, q2
-    vadd.s16        q10, q10, q2
-      /* Transpose */
-      vtrn.16         q8, q9
-    vsub.s16        q11, q12, q1
-      vtrn.16         q14, q15
-    vadd.s16        q12, q12, q1
-      vtrn.16         q10, q11
-      vtrn.16         q12, q13
-      vtrn.32         q9, q11
-      vtrn.32         q12, q14
-      vtrn.32         q8, q10
-      vtrn.32         q13, q15
-      vswp            d28, d21
-      vswp            d26, d19
-    /* 1-D IDCT, pass 2 */
-    vsub.s16        q2, q10, q14
-      vswp            d30, d23
-    vadd.s16        q14, q10, q14
-      vswp            d24, d17
-    vsub.s16        q1, q11, q13
-    vadd.s16        q13, q11, q13
-    vsub.s16        q5, q9, q15
-    vadd.s16        q15, q9, q15
-    vqdmulh.s16     q4, q2, XFIX_1_414213562
-    vqdmulh.s16     q6, q1, XFIX_2_613125930
-    vadd.s16        q3, q1, q1
-    vsub.s16        q1, q5, q1
-    vadd.s16        q10, q2, q4
-    vqdmulh.s16     q4, q1, XFIX_1_847759065
-    vsub.s16        q2, q15, q13
-    vadd.s16        q3, q3, q6
-    vqdmulh.s16     q6, q2, XFIX_1_414213562
-    vadd.s16        q1, q1, q4
-    vqdmulh.s16     q4, q5, XFIX_1_082392200
-    vsub.s16        q10, q10, q14
-    vadd.s16        q2, q2, q6
-    vsub.s16        q6, q8, q12
-    vadd.s16        q12, q8, q12
-    vadd.s16        q9, q5, q4
-    vadd.s16        q5, q6, q10
-    vsub.s16        q10, q6, q10
-    vadd.s16        q6, q15, q13
-    vadd.s16        q8, q12, q14
-    vsub.s16        q3, q6, q3
-    vsub.s16        q12, q12, q14
-    vsub.s16        q3, q3, q1
-    vsub.s16        q1, q9, q1
-    vadd.s16        q2, q3, q2
-    vsub.s16        q15, q8, q6
-    vadd.s16        q1, q1, q2
-    vadd.s16        q8, q8, q6
-    vadd.s16        q14, q5, q3
-    vsub.s16        q9, q5, q3
-    vsub.s16        q13, q10, q2
-    vpop            {d8-d13}      /* restore NEON registers */
-    vadd.s16        q10, q10, q2
-    vsub.s16        q11, q12, q1
-    vadd.s16        q12, q12, q1
-    /* Descale to 8-bit and range limit */
-    vmov.u8         q0, #0x80
-    vqshrn.s16      d16, q8, #5
-    vqshrn.s16      d17, q9, #5
-    vqshrn.s16      d18, q10, #5
-    vqshrn.s16      d19, q11, #5
-    vqshrn.s16      d20, q12, #5
-    vqshrn.s16      d21, q13, #5
-    vqshrn.s16      d22, q14, #5
-    vqshrn.s16      d23, q15, #5
-    vadd.u8         q8, q8, q0
-    vadd.u8         q9, q9, q0
-    vadd.u8         q10, q10, q0
-    vadd.u8         q11, q11, q0
-    /* Transpose the final 8-bit samples */
-    vtrn.16         q8, q9
-    vtrn.16         q10, q11
-    vtrn.32         q8, q10
-    vtrn.32         q9, q11
-    vtrn.8          d16, d17
-    vtrn.8          d18, d19
-      /* Store results to the output buffer */
-      ldmia           OUTPUT_BUF!, {TMP1, TMP2}
-      add             TMP1, TMP1, OUTPUT_COL
-      add             TMP2, TMP2, OUTPUT_COL
-      vst1.8          {d16}, [TMP1]
-      vst1.8          {d17}, [TMP2]
-      ldmia           OUTPUT_BUF!, {TMP1, TMP2}
-      add             TMP1, TMP1, OUTPUT_COL
-      add             TMP2, TMP2, OUTPUT_COL
-      vst1.8          {d18}, [TMP1]
-    vtrn.8          d20, d21
-      vst1.8          {d19}, [TMP2]
-      ldmia           OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
-      add             TMP1, TMP1, OUTPUT_COL
-      add             TMP2, TMP2, OUTPUT_COL
-      add             TMP3, TMP3, OUTPUT_COL
-      add             TMP4, TMP4, OUTPUT_COL
-      vst1.8          {d20}, [TMP1]
-    vtrn.8          d22, d23
-      vst1.8          {d21}, [TMP2]
-      vst1.8          {d22}, [TMP3]
-      vst1.8          {d23}, [TMP4]
-    bx              lr
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_4x4_neon
- *
- * This function contains inverse-DCT code for getting reduced-size
- * 4x4 pixels output from an 8x8 DCT block. It uses the same  calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_4x4'
- * function from jpeg-6b (jidctred.c).
- *
- * NOTE: jpeg-8 has an improved implementation of 4x4 inverse-DCT, which
- *       requires much less arithmetic operations and hence should be faster.
- *       The primary purpose of this particular NEON optimized function is
- *       bit exact compatibility with jpeg-6b.
- *
- * TODO: a bit better instructions scheduling can be achieved by expanding
- *       idct_helper/transpose_4x4 macros and reordering instructions,
- *       but readability will suffer somewhat.
- */
-
-#define CONST_BITS  13
-
-#define FIX_0_211164243  (1730)   /* FIX(0.211164243) */
-#define FIX_0_509795579  (4176)   /* FIX(0.509795579) */
-#define FIX_0_601344887  (4926)   /* FIX(0.601344887) */
-#define FIX_0_720959822  (5906)   /* FIX(0.720959822) */
-#define FIX_0_765366865  (6270)   /* FIX(0.765366865) */
-#define FIX_0_850430095  (6967)   /* FIX(0.850430095) */
-#define FIX_0_899976223  (7373)   /* FIX(0.899976223) */
-#define FIX_1_061594337  (8697)   /* FIX(1.061594337) */
-#define FIX_1_272758580  (10426)  /* FIX(1.272758580) */
-#define FIX_1_451774981  (11893)  /* FIX(1.451774981) */
-#define FIX_1_847759065  (15137)  /* FIX(1.847759065) */
-#define FIX_2_172734803  (17799)  /* FIX(2.172734803) */
-#define FIX_2_562915447  (20995)  /* FIX(2.562915447) */
-#define FIX_3_624509785  (29692)  /* FIX(3.624509785) */
-
-.balign 16
-jsimd_idct_4x4_neon_consts:
-  .short FIX_1_847759065        /* d0[0] */
-  .short -FIX_0_765366865       /* d0[1] */
-  .short -FIX_0_211164243       /* d0[2] */
-  .short FIX_1_451774981        /* d0[3] */
-  .short -FIX_2_172734803       /* d1[0] */
-  .short FIX_1_061594337        /* d1[1] */
-  .short -FIX_0_509795579       /* d1[2] */
-  .short -FIX_0_601344887       /* d1[3] */
-  .short FIX_0_899976223        /* d2[0] */
-  .short FIX_2_562915447        /* d2[1] */
-  .short 1 << (CONST_BITS + 1)  /* d2[2] */
-  .short 0                      /* d2[3] */
-
-.macro idct_helper x4, x6, x8, x10, x12, x14, x16, shift, y26, y27, y28, y29
-    vmull.s16       q14, \x4, d2[2]
-    vmlal.s16       q14, \x8, d0[0]
-    vmlal.s16       q14, \x14, d0[1]
-
-    vmull.s16       q13, \x16, d1[2]
-    vmlal.s16       q13, \x12, d1[3]
-    vmlal.s16       q13, \x10, d2[0]
-    vmlal.s16       q13, \x6, d2[1]
-
-    vmull.s16       q15, \x4, d2[2]
-    vmlsl.s16       q15, \x8, d0[0]
-    vmlsl.s16       q15, \x14, d0[1]
-
-    vmull.s16       q12, \x16, d0[2]
-    vmlal.s16       q12, \x12, d0[3]
-    vmlal.s16       q12, \x10, d1[0]
-    vmlal.s16       q12, \x6, d1[1]
-
-    vadd.s32        q10, q14, q13
-    vsub.s32        q14, q14, q13
-
-  .if \shift > 16
-    vrshr.s32       q10, q10, #\shift
-    vrshr.s32       q14, q14, #\shift
-    vmovn.s32       \y26, q10
-    vmovn.s32       \y29, q14
-  .else
-    vrshrn.s32      \y26, q10, #\shift
-    vrshrn.s32      \y29, q14, #\shift
-  .endif
-
-    vadd.s32        q10, q15, q12
-    vsub.s32        q15, q15, q12
-
-  .if \shift > 16
-    vrshr.s32       q10, q10, #\shift
-    vrshr.s32       q15, q15, #\shift
-    vmovn.s32       \y27, q10
-    vmovn.s32       \y28, q15
-  .else
-    vrshrn.s32      \y27, q10, #\shift
-    vrshrn.s32      \y28, q15, #\shift
-  .endif
-.endm
-
-asm_function jsimd_idct_4x4_neon
-
-    DCT_TABLE       .req r0
-    COEF_BLOCK      .req r1
-    OUTPUT_BUF      .req r2
-    OUTPUT_COL      .req r3
-    TMP1            .req r0
-    TMP2            .req r1
-    TMP3            .req r2
-    TMP4            .req ip
-
-    vpush           {d8-d15}
-
-    /* Load constants (d3 is just used for padding) */
-    adr             TMP4, jsimd_idct_4x4_neon_consts
-    vld1.16         {d0, d1, d2, d3}, [TMP4, :128]
-
-    /* Load all COEF_BLOCK into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d4      | d5
-     *   1 | d6      | d7
-     *   2 | d8      | d9
-     *   3 | d10     | d11
-     *   4 | -       | -
-     *   5 | d12     | d13
-     *   6 | d14     | d15
-     *   7 | d16     | d17
-     */
-    vld1.16         {d4, d5, d6, d7}, [COEF_BLOCK, :128]!
-    vld1.16         {d8, d9, d10, d11}, [COEF_BLOCK, :128]!
-    add COEF_BLOCK, COEF_BLOCK, #16
-    vld1.16         {d12, d13, d14, d15}, [COEF_BLOCK, :128]!
-    vld1.16         {d16, d17}, [COEF_BLOCK, :128]!
-    /* dequantize */
-    vld1.16         {d18, d19, d20, d21}, [DCT_TABLE, :128]!
-    vmul.s16        q2, q2, q9
-    vld1.16         {d22, d23, d24, d25}, [DCT_TABLE, :128]!
-    vmul.s16        q3, q3, q10
-    vmul.s16        q4, q4, q11
-    add             DCT_TABLE, DCT_TABLE, #16
-    vld1.16         {d26, d27, d28, d29}, [DCT_TABLE, :128]!
-    vmul.s16        q5, q5, q12
-    vmul.s16        q6, q6, q13
-    vld1.16         {d30, d31}, [DCT_TABLE, :128]!
-    vmul.s16        q7, q7, q14
-    vmul.s16        q8, q8, q15
-
-    /* Pass 1 */
-    idct_helper     d4, d6, d8, d10, d12, d14, d16, 12, d4, d6, d8, d10
-    transpose_4x4   d4, d6, d8, d10
-    idct_helper     d5, d7, d9, d11, d13, d15, d17, 12, d5, d7, d9, d11
-    transpose_4x4   d5, d7, d9, d11
-
-    /* Pass 2 */
-    idct_helper     d4, d6, d8, d10, d7, d9, d11, 19, d26, d27, d28, d29
-    transpose_4x4   d26, d27, d28, d29
-
-    /* Range limit */
-    vmov.u16        q15, #0x80
-    vadd.s16        q13, q13, q15
-    vadd.s16        q14, q14, q15
-    vqmovun.s16     d26, q13
-    vqmovun.s16     d27, q14
-
-    /* Store results to the output buffer */
-    ldmia           OUTPUT_BUF, {TMP1, TMP2, TMP3, TMP4}
-    add             TMP1, TMP1, OUTPUT_COL
-    add             TMP2, TMP2, OUTPUT_COL
-    add             TMP3, TMP3, OUTPUT_COL
-    add             TMP4, TMP4, OUTPUT_COL
-
-#if defined(__ARMEL__) && !RESPECT_STRICT_ALIGNMENT
-    /* We can use much less instructions on little endian systems if the
-     * OS kernel is not configured to trap unaligned memory accesses
-     */
-    vst1.32         {d26[0]}, [TMP1]!
-    vst1.32         {d27[0]}, [TMP3]!
-    vst1.32         {d26[1]}, [TMP2]!
-    vst1.32         {d27[1]}, [TMP4]!
-#else
-    vst1.8          {d26[0]}, [TMP1]!
-    vst1.8          {d27[0]}, [TMP3]!
-    vst1.8          {d26[1]}, [TMP1]!
-    vst1.8          {d27[1]}, [TMP3]!
-    vst1.8          {d26[2]}, [TMP1]!
-    vst1.8          {d27[2]}, [TMP3]!
-    vst1.8          {d26[3]}, [TMP1]!
-    vst1.8          {d27[3]}, [TMP3]!
-
-    vst1.8          {d26[4]}, [TMP2]!
-    vst1.8          {d27[4]}, [TMP4]!
-    vst1.8          {d26[5]}, [TMP2]!
-    vst1.8          {d27[5]}, [TMP4]!
-    vst1.8          {d26[6]}, [TMP2]!
-    vst1.8          {d27[6]}, [TMP4]!
-    vst1.8          {d26[7]}, [TMP2]!
-    vst1.8          {d27[7]}, [TMP4]!
-#endif
-
-    vpop            {d8-d15}
-    bx              lr
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-
-.purgem idct_helper
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_2x2_neon
- *
- * This function contains inverse-DCT code for getting reduced-size
- * 2x2 pixels output from an 8x8 DCT block. It uses the same  calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_2x2'
- * function from jpeg-6b (jidctred.c).
- *
- * NOTE: jpeg-8 has an improved implementation of 2x2 inverse-DCT, which
- *       requires much less arithmetic operations and hence should be faster.
- *       The primary purpose of this particular NEON optimized function is
- *       bit exact compatibility with jpeg-6b.
- */
-
-.balign 8
-jsimd_idct_2x2_neon_consts:
-  .short -FIX_0_720959822  /* d0[0] */
-  .short FIX_0_850430095   /* d0[1] */
-  .short -FIX_1_272758580  /* d0[2] */
-  .short FIX_3_624509785   /* d0[3] */
-
-.macro idct_helper x4, x6, x10, x12, x16, shift, y26, y27
-    vshll.s16       q14, \x4, #15
-    vmull.s16       q13, \x6, d0[3]
-    vmlal.s16       q13, \x10, d0[2]
-    vmlal.s16       q13, \x12, d0[1]
-    vmlal.s16       q13, \x16, d0[0]
-
-    vadd.s32        q10, q14, q13
-    vsub.s32        q14, q14, q13
-
-  .if \shift > 16
-    vrshr.s32       q10, q10, #\shift
-    vrshr.s32       q14, q14, #\shift
-    vmovn.s32       \y26, q10
-    vmovn.s32       \y27, q14
-  .else
-    vrshrn.s32      \y26, q10, #\shift
-    vrshrn.s32      \y27, q14, #\shift
-  .endif
-.endm
-
-asm_function jsimd_idct_2x2_neon
-
-    DCT_TABLE       .req r0
-    COEF_BLOCK      .req r1
-    OUTPUT_BUF      .req r2
-    OUTPUT_COL      .req r3
-    TMP1            .req r0
-    TMP2            .req ip
-
-    vpush           {d8-d15}
-
-    /* Load constants */
-    adr             TMP2, jsimd_idct_2x2_neon_consts
-    vld1.16         {d0}, [TMP2, :64]
-
-    /* Load all COEF_BLOCK into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d4      | d5
-     *   1 | d6      | d7
-     *   2 | -       | -
-     *   3 | d10     | d11
-     *   4 | -       | -
-     *   5 | d12     | d13
-     *   6 | -       | -
-     *   7 | d16     | d17
-     */
-    vld1.16         {d4, d5, d6, d7}, [COEF_BLOCK, :128]!
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    vld1.16         {d10, d11}, [COEF_BLOCK, :128]!
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    vld1.16         {d12, d13}, [COEF_BLOCK, :128]!
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    vld1.16         {d16, d17}, [COEF_BLOCK, :128]!
-    /* Dequantize */
-    vld1.16         {d18, d19, d20, d21}, [DCT_TABLE, :128]!
-    vmul.s16        q2, q2, q9
-    vmul.s16        q3, q3, q10
-    add             DCT_TABLE, DCT_TABLE, #16
-    vld1.16         {d24, d25}, [DCT_TABLE, :128]!
-    vmul.s16        q5, q5, q12
-    add             DCT_TABLE, DCT_TABLE, #16
-    vld1.16         {d26, d27}, [DCT_TABLE, :128]!
-    vmul.s16        q6, q6, q13
-    add             DCT_TABLE, DCT_TABLE, #16
-    vld1.16         {d30, d31}, [DCT_TABLE, :128]!
-    vmul.s16        q8, q8, q15
-
-    /* Pass 1 */
-#if 0
-    idct_helper     d4, d6, d10, d12, d16, 13, d4, d6
-    transpose_4x4   d4, d6, d8, d10
-    idct_helper     d5, d7, d11, d13, d17, 13, d5, d7
-    transpose_4x4   d5, d7, d9, d11
-#else
-    vmull.s16       q13, d6, d0[3]
-    vmlal.s16       q13, d10, d0[2]
-    vmlal.s16       q13, d12, d0[1]
-    vmlal.s16       q13, d16, d0[0]
-    vmull.s16       q12, d7, d0[3]
-    vmlal.s16       q12, d11, d0[2]
-    vmlal.s16       q12, d13, d0[1]
-    vmlal.s16       q12, d17, d0[0]
-    vshll.s16       q14, d4, #15
-    vshll.s16       q15, d5, #15
-    vadd.s32        q10, q14, q13
-    vsub.s32        q14, q14, q13
-    vrshrn.s32      d4, q10, #13
-    vrshrn.s32      d6, q14, #13
-    vadd.s32        q10, q15, q12
-    vsub.s32        q14, q15, q12
-    vrshrn.s32      d5, q10, #13
-    vrshrn.s32      d7, q14, #13
-    vtrn.16         q2, q3
-    vtrn.32         q3, q5
-#endif
-
-    /* Pass 2 */
-    idct_helper     d4, d6, d10, d7, d11, 20, d26, d27
-
-    /* Range limit */
-    vmov.u16        q15, #0x80
-    vadd.s16        q13, q13, q15
-    vqmovun.s16     d26, q13
-    vqmovun.s16     d27, q13
-
-    /* Store results to the output buffer */
-    ldmia           OUTPUT_BUF, {TMP1, TMP2}
-    add             TMP1, TMP1, OUTPUT_COL
-    add             TMP2, TMP2, OUTPUT_COL
-
-    vst1.8          {d26[0]}, [TMP1]!
-    vst1.8          {d27[4]}, [TMP1]!
-    vst1.8          {d26[1]}, [TMP2]!
-    vst1.8          {d27[5]}, [TMP2]!
-
-    vpop            {d8-d15}
-    bx              lr
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-
-.purgem idct_helper
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_ycc_extrgb_convert_neon
- * jsimd_ycc_extbgr_convert_neon
- * jsimd_ycc_extrgbx_convert_neon
- * jsimd_ycc_extbgrx_convert_neon
- * jsimd_ycc_extxbgr_convert_neon
- * jsimd_ycc_extxrgb_convert_neon
- *
- * Colorspace conversion YCbCr -> RGB
- */
-
-
-.macro do_load size
-  .if \size == 8
-    vld1.8          {d4}, [U, :64]!
-    vld1.8          {d5}, [V, :64]!
-    vld1.8          {d0}, [Y, :64]!
-    pld             [U, #64]
-    pld             [V, #64]
-    pld             [Y, #64]
-  .elseif \size == 4
-    vld1.8          {d4[0]}, [U]!
-    vld1.8          {d4[1]}, [U]!
-    vld1.8          {d4[2]}, [U]!
-    vld1.8          {d4[3]}, [U]!
-    vld1.8          {d5[0]}, [V]!
-    vld1.8          {d5[1]}, [V]!
-    vld1.8          {d5[2]}, [V]!
-    vld1.8          {d5[3]}, [V]!
-    vld1.8          {d0[0]}, [Y]!
-    vld1.8          {d0[1]}, [Y]!
-    vld1.8          {d0[2]}, [Y]!
-    vld1.8          {d0[3]}, [Y]!
-  .elseif \size == 2
-    vld1.8          {d4[4]}, [U]!
-    vld1.8          {d4[5]}, [U]!
-    vld1.8          {d5[4]}, [V]!
-    vld1.8          {d5[5]}, [V]!
-    vld1.8          {d0[4]}, [Y]!
-    vld1.8          {d0[5]}, [Y]!
-  .elseif \size == 1
-    vld1.8          {d4[6]}, [U]!
-    vld1.8          {d5[6]}, [V]!
-    vld1.8          {d0[6]}, [Y]!
-  .else
-    .error unsupported macroblock size
-  .endif
-.endm
-
-.macro do_store bpp, size
-  .if \bpp == 24
-    .if \size == 8
-      vst3.8        {d10, d11, d12}, [RGB]!
-    .elseif \size == 4
-      vst3.8        {d10[0], d11[0], d12[0]}, [RGB]!
-      vst3.8        {d10[1], d11[1], d12[1]}, [RGB]!
-      vst3.8        {d10[2], d11[2], d12[2]}, [RGB]!
-      vst3.8        {d10[3], d11[3], d12[3]}, [RGB]!
-    .elseif \size == 2
-      vst3.8        {d10[4], d11[4], d12[4]}, [RGB]!
-      vst3.8        {d10[5], d11[5], d12[5]}, [RGB]!
-    .elseif \size == 1
-      vst3.8        {d10[6], d11[6], d12[6]}, [RGB]!
-    .else
-      .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 32
-    .if \size == 8
-      vst4.8        {d10, d11, d12, d13}, [RGB]!
-    .elseif \size == 4
-      vst4.8        {d10[0], d11[0], d12[0], d13[0]}, [RGB]!
-      vst4.8        {d10[1], d11[1], d12[1], d13[1]}, [RGB]!
-      vst4.8        {d10[2], d11[2], d12[2], d13[2]}, [RGB]!
-      vst4.8        {d10[3], d11[3], d12[3], d13[3]}, [RGB]!
-    .elseif \size == 2
-      vst4.8        {d10[4], d11[4], d12[4], d13[4]}, [RGB]!
-      vst4.8        {d10[5], d11[5], d12[5], d13[5]}, [RGB]!
-    .elseif \size == 1
-      vst4.8        {d10[6], d11[6], d12[6], d13[6]}, [RGB]!
-    .else
-      .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 16
-    .if \size == 8
-      vst1.16       {q15}, [RGB]!
-    .elseif \size == 4
-      vst1.16       {d30}, [RGB]!
-    .elseif \size == 2
-      vst1.16       {d31[0]}, [RGB]!
-      vst1.16       {d31[1]}, [RGB]!
-    .elseif \size == 1
-      vst1.16       {d31[2]}, [RGB]!
-    .else
-      .error unsupported macroblock size
-    .endif
-  .else
-    .error unsupported bpp
-  .endif
-.endm
-
-.macro generate_jsimd_ycc_rgb_convert_neon colorid, bpp, r_offs, g_offs, b_offs
-
-/*
- * 2-stage pipelined YCbCr->RGB conversion
- */
-
-.macro do_yuv_to_rgb_stage1
-    vaddw.u8        q3, q1, d4      /* q3 = u - 128 */
-    vaddw.u8        q4, q1, d5      /* q2 = v - 128 */
-    vmull.s16       q10, d6, d1[1]  /* multiply by -11277 */
-    vmlal.s16       q10, d8, d1[2]  /* multiply by -23401 */
-    vmull.s16       q11, d7, d1[1]  /* multiply by -11277 */
-    vmlal.s16       q11, d9, d1[2]  /* multiply by -23401 */
-    vmull.s16       q12, d8, d1[0]  /* multiply by 22971 */
-    vmull.s16       q13, d9, d1[0]  /* multiply by 22971 */
-    vmull.s16       q14, d6, d1[3]  /* multiply by 29033 */
-    vmull.s16       q15, d7, d1[3]  /* multiply by 29033 */
-.endm
-
-.macro do_yuv_to_rgb_stage2
-    vrshrn.s32      d20, q10, #15
-    vrshrn.s32      d21, q11, #15
-    vrshrn.s32      d24, q12, #14
-    vrshrn.s32      d25, q13, #14
-    vrshrn.s32      d28, q14, #14
-    vrshrn.s32      d29, q15, #14
-    vaddw.u8        q11, q10, d0
-    vaddw.u8        q12, q12, d0
-    vaddw.u8        q14, q14, d0
-  .if \bpp != 16
-    vqmovun.s16     d1\g_offs, q11
-    vqmovun.s16     d1\r_offs, q12
-    vqmovun.s16     d1\b_offs, q14
-  .else  /* rgb565 */
-    vqshlu.s16      q13, q11, #8
-    vqshlu.s16      q15, q12, #8
-    vqshlu.s16      q14, q14, #8
-    vsri.u16        q15, q13, #5
-    vsri.u16        q15, q14, #11
-  .endif
-.endm
-
-.macro do_yuv_to_rgb_stage2_store_load_stage1
-                                       /* "do_yuv_to_rgb_stage2" and "store" */
-                                       vrshrn.s32      d20, q10, #15
-    /* "load" and "do_yuv_to_rgb_stage1" */
-    pld             [U, #64]
-                                       vrshrn.s32      d21, q11, #15
-    pld             [V, #64]
-                                       vrshrn.s32      d24, q12, #14
-                                       vrshrn.s32      d25, q13, #14
-    vld1.8          {d4}, [U, :64]!
-                                       vrshrn.s32      d28, q14, #14
-    vld1.8          {d5}, [V, :64]!
-                                       vrshrn.s32      d29, q15, #14
-    vaddw.u8        q3, q1, d4      /* q3 = u - 128 */
-    vaddw.u8        q4, q1, d5      /* q2 = v - 128 */
-                                       vaddw.u8        q11, q10, d0
-    vmull.s16       q10, d6, d1[1]  /* multiply by -11277 */
-    vmlal.s16       q10, d8, d1[2]  /* multiply by -23401 */
-                                       vaddw.u8        q12, q12, d0
-                                       vaddw.u8        q14, q14, d0
-  .if \bpp != 16  /**************** rgb24/rgb32 ******************************/
-                                       vqmovun.s16     d1\g_offs, q11
-    pld             [Y, #64]
-                                       vqmovun.s16     d1\r_offs, q12
-    vld1.8          {d0}, [Y, :64]!
-                                       vqmovun.s16     d1\b_offs, q14
-    vmull.s16       q11, d7, d1[1]  /* multiply by -11277 */
-    vmlal.s16       q11, d9, d1[2]  /* multiply by -23401 */
-                                       do_store        \bpp, 8
-    vmull.s16       q12, d8, d1[0]  /* multiply by 22971 */
-    vmull.s16       q13, d9, d1[0]  /* multiply by 22971 */
-    vmull.s16       q14, d6, d1[3]  /* multiply by 29033 */
-    vmull.s16       q15, d7, d1[3]  /* multiply by 29033 */
-  .else  /**************************** rgb565 ********************************/
-                                       vqshlu.s16      q13, q11, #8
-    pld             [Y, #64]
-                                       vqshlu.s16      q15, q12, #8
-                                       vqshlu.s16      q14, q14, #8
-    vld1.8          {d0}, [Y, :64]!
-    vmull.s16       q11, d7, d1[1]
-    vmlal.s16       q11, d9, d1[2]
-                                       vsri.u16        q15, q13, #5
-    vmull.s16       q12, d8, d1[0]
-                                       vsri.u16        q15, q14, #11
-    vmull.s16       q13, d9, d1[0]
-    vmull.s16       q14, d6, d1[3]
-                                       do_store        \bpp, 8
-    vmull.s16       q15, d7, d1[3]
-  .endif
-.endm
-
-.macro do_yuv_to_rgb
-    do_yuv_to_rgb_stage1
-    do_yuv_to_rgb_stage2
-.endm
-
-/* Apple gas crashes on adrl, work around that by using adr.
- * But this requires a copy of these constants for each function.
- */
-
-.balign 16
-jsimd_ycc_\colorid\()_neon_consts:
-  .short 0,      0,     0,      0
-  .short 22971, -11277, -23401, 29033
-  .short -128,  -128,   -128,   -128
-  .short -128,  -128,   -128,   -128
-
-asm_function jsimd_ycc_\colorid\()_convert_neon
-    OUTPUT_WIDTH    .req r0
-    INPUT_BUF       .req r1
-    INPUT_ROW       .req r2
-    OUTPUT_BUF      .req r3
-    NUM_ROWS        .req r4
-
-    INPUT_BUF0      .req r5
-    INPUT_BUF1      .req r6
-    INPUT_BUF2      .req INPUT_BUF
-
-    RGB             .req r7
-    Y               .req r8
-    U               .req r9
-    V               .req r10
-    N               .req ip
-
-    /* Load constants to d1, d2, d3 (d0 is just used for padding) */
-    adr             ip, jsimd_ycc_\colorid\()_neon_consts
-    vld1.16         {d0, d1, d2, d3}, [ip, :128]
-
-    /* Save ARM registers and handle input arguments */
-    push            {r4, r5, r6, r7, r8, r9, r10, lr}
-    ldr             NUM_ROWS, [sp, #(4 * 8)]
-    ldr             INPUT_BUF0, [INPUT_BUF]
-    ldr             INPUT_BUF1, [INPUT_BUF, #4]
-    ldr             INPUT_BUF2, [INPUT_BUF, #8]
-    .unreq          INPUT_BUF
-
-    /* Save NEON registers */
-    vpush           {d8-d15}
-
-    /* Initially set d10, d11, d12, d13 to 0xFF */
-    vmov.u8         q5, #255
-    vmov.u8         q6, #255
-
-    /* Outer loop over scanlines */
-    cmp             NUM_ROWS, #1
-    blt             9f
-0:
-    ldr             Y, [INPUT_BUF0, INPUT_ROW, lsl #2]
-    ldr             U, [INPUT_BUF1, INPUT_ROW, lsl #2]
-    mov             N, OUTPUT_WIDTH
-    ldr             V, [INPUT_BUF2, INPUT_ROW, lsl #2]
-    add             INPUT_ROW, INPUT_ROW, #1
-    ldr             RGB, [OUTPUT_BUF], #4
-
-    /* Inner loop over pixels */
-    subs            N, N, #8
-    blt             3f
-    do_load         8
-    do_yuv_to_rgb_stage1
-    subs            N, N, #8
-    blt             2f
-1:
-    do_yuv_to_rgb_stage2_store_load_stage1
-    subs            N, N, #8
-    bge             1b
-2:
-    do_yuv_to_rgb_stage2
-    do_store        \bpp, 8
-    tst             N, #7
-    beq             8f
-3:
-    tst             N, #4
-    beq             3f
-    do_load         4
-3:
-    tst             N, #2
-    beq             4f
-    do_load         2
-4:
-    tst             N, #1
-    beq             5f
-    do_load         1
-5:
-    do_yuv_to_rgb
-    tst             N, #4
-    beq             6f
-    do_store        \bpp, 4
-6:
-    tst             N, #2
-    beq             7f
-    do_store        \bpp, 2
-7:
-    tst             N, #1
-    beq             8f
-    do_store        \bpp, 1
-8:
-    subs            NUM_ROWS, NUM_ROWS, #1
-    bgt             0b
-9:
-    /* Restore all registers and return */
-    vpop            {d8-d15}
-    pop             {r4, r5, r6, r7, r8, r9, r10, pc}
-
-    .unreq          OUTPUT_WIDTH
-    .unreq          INPUT_ROW
-    .unreq          OUTPUT_BUF
-    .unreq          NUM_ROWS
-    .unreq          INPUT_BUF0
-    .unreq          INPUT_BUF1
-    .unreq          INPUT_BUF2
-    .unreq          RGB
-    .unreq          Y
-    .unreq          U
-    .unreq          V
-    .unreq          N
-
-.purgem do_yuv_to_rgb
-.purgem do_yuv_to_rgb_stage1
-.purgem do_yuv_to_rgb_stage2
-.purgem do_yuv_to_rgb_stage2_store_load_stage1
-
-.endm
-
-/*--------------------------------- id ----- bpp R  G  B */
-generate_jsimd_ycc_rgb_convert_neon extrgb,  24, 0, 1, 2
-generate_jsimd_ycc_rgb_convert_neon extbgr,  24, 2, 1, 0
-generate_jsimd_ycc_rgb_convert_neon extrgbx, 32, 0, 1, 2
-generate_jsimd_ycc_rgb_convert_neon extbgrx, 32, 2, 1, 0
-generate_jsimd_ycc_rgb_convert_neon extxbgr, 32, 3, 2, 1
-generate_jsimd_ycc_rgb_convert_neon extxrgb, 32, 1, 2, 3
-generate_jsimd_ycc_rgb_convert_neon rgb565,  16, 0, 0, 0
-
-.purgem do_load
-.purgem do_store
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_extrgb_ycc_convert_neon
- * jsimd_extbgr_ycc_convert_neon
- * jsimd_extrgbx_ycc_convert_neon
- * jsimd_extbgrx_ycc_convert_neon
- * jsimd_extxbgr_ycc_convert_neon
- * jsimd_extxrgb_ycc_convert_neon
- *
- * Colorspace conversion RGB -> YCbCr
- */
-
-.macro do_store size
-  .if \size == 8
-    vst1.8          {d20}, [Y]!
-    vst1.8          {d21}, [U]!
-    vst1.8          {d22}, [V]!
-  .elseif \size == 4
-    vst1.8          {d20[0]}, [Y]!
-    vst1.8          {d20[1]}, [Y]!
-    vst1.8          {d20[2]}, [Y]!
-    vst1.8          {d20[3]}, [Y]!
-    vst1.8          {d21[0]}, [U]!
-    vst1.8          {d21[1]}, [U]!
-    vst1.8          {d21[2]}, [U]!
-    vst1.8          {d21[3]}, [U]!
-    vst1.8          {d22[0]}, [V]!
-    vst1.8          {d22[1]}, [V]!
-    vst1.8          {d22[2]}, [V]!
-    vst1.8          {d22[3]}, [V]!
-  .elseif \size == 2
-    vst1.8          {d20[4]}, [Y]!
-    vst1.8          {d20[5]}, [Y]!
-    vst1.8          {d21[4]}, [U]!
-    vst1.8          {d21[5]}, [U]!
-    vst1.8          {d22[4]}, [V]!
-    vst1.8          {d22[5]}, [V]!
-  .elseif \size == 1
-    vst1.8          {d20[6]}, [Y]!
-    vst1.8          {d21[6]}, [U]!
-    vst1.8          {d22[6]}, [V]!
-  .else
-    .error unsupported macroblock size
-  .endif
-.endm
-
-.macro do_load bpp, size
-  .if \bpp == 24
-    .if \size == 8
-      vld3.8        {d10, d11, d12}, [RGB]!
-      pld           [RGB, #128]
-    .elseif \size == 4
-      vld3.8        {d10[0], d11[0], d12[0]}, [RGB]!
-      vld3.8        {d10[1], d11[1], d12[1]}, [RGB]!
-      vld3.8        {d10[2], d11[2], d12[2]}, [RGB]!
-      vld3.8        {d10[3], d11[3], d12[3]}, [RGB]!
-    .elseif \size == 2
-      vld3.8        {d10[4], d11[4], d12[4]}, [RGB]!
-      vld3.8        {d10[5], d11[5], d12[5]}, [RGB]!
-    .elseif \size == 1
-      vld3.8        {d10[6], d11[6], d12[6]}, [RGB]!
-    .else
-      .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 32
-    .if \size == 8
-      vld4.8        {d10, d11, d12, d13}, [RGB]!
-      pld           [RGB, #128]
-    .elseif \size == 4
-      vld4.8        {d10[0], d11[0], d12[0], d13[0]}, [RGB]!
-      vld4.8        {d10[1], d11[1], d12[1], d13[1]}, [RGB]!
-      vld4.8        {d10[2], d11[2], d12[2], d13[2]}, [RGB]!
-      vld4.8        {d10[3], d11[3], d12[3], d13[3]}, [RGB]!
-    .elseif \size == 2
-      vld4.8        {d10[4], d11[4], d12[4], d13[4]}, [RGB]!
-      vld4.8        {d10[5], d11[5], d12[5], d13[5]}, [RGB]!
-    .elseif \size == 1
-      vld4.8        {d10[6], d11[6], d12[6], d13[6]}, [RGB]!
-    .else
-      .error unsupported macroblock size
-    .endif
-  .else
-    .error unsupported bpp
-  .endif
-.endm
-
-.macro generate_jsimd_rgb_ycc_convert_neon colorid, bpp, r_offs, g_offs, b_offs
-
-/*
- * 2-stage pipelined RGB->YCbCr conversion
- */
-
-.macro do_rgb_to_yuv_stage1
-    vmovl.u8        q2, d1\r_offs  /* r = { d4, d5 } */
-    vmovl.u8        q3, d1\g_offs  /* g = { d6, d7 } */
-    vmovl.u8        q4, d1\b_offs  /* b = { d8, d9 } */
-    vmull.u16       q7, d4, d0[0]
-    vmlal.u16       q7, d6, d0[1]
-    vmlal.u16       q7, d8, d0[2]
-    vmull.u16       q8, d5, d0[0]
-    vmlal.u16       q8, d7, d0[1]
-    vmlal.u16       q8, d9, d0[2]
-    vrev64.32       q9, q1
-    vrev64.32       q13, q1
-    vmlsl.u16       q9, d4, d0[3]
-    vmlsl.u16       q9, d6, d1[0]
-    vmlal.u16       q9, d8, d1[1]
-    vmlsl.u16       q13, d5, d0[3]
-    vmlsl.u16       q13, d7, d1[0]
-    vmlal.u16       q13, d9, d1[1]
-    vrev64.32       q14, q1
-    vrev64.32       q15, q1
-    vmlal.u16       q14, d4, d1[1]
-    vmlsl.u16       q14, d6, d1[2]
-    vmlsl.u16       q14, d8, d1[3]
-    vmlal.u16       q15, d5, d1[1]
-    vmlsl.u16       q15, d7, d1[2]
-    vmlsl.u16       q15, d9, d1[3]
-.endm
-
-.macro do_rgb_to_yuv_stage2
-    vrshrn.u32      d20, q7, #16
-    vrshrn.u32      d21, q8, #16
-    vshrn.u32       d22, q9, #16
-    vshrn.u32       d23, q13, #16
-    vshrn.u32       d24, q14, #16
-    vshrn.u32       d25, q15, #16
-    vmovn.u16       d20, q10       /* d20 = y */
-    vmovn.u16       d21, q11       /* d21 = u */
-    vmovn.u16       d22, q12       /* d22 = v */
-.endm
-
-.macro do_rgb_to_yuv
-    do_rgb_to_yuv_stage1
-    do_rgb_to_yuv_stage2
-.endm
-
-.macro do_rgb_to_yuv_stage2_store_load_stage1
-      vrshrn.u32      d20, q7, #16
-      vrshrn.u32      d21, q8, #16
-      vshrn.u32       d22, q9, #16
-    vrev64.32       q9, q1
-      vshrn.u32       d23, q13, #16
-    vrev64.32       q13, q1
-      vshrn.u32       d24, q14, #16
-      vshrn.u32       d25, q15, #16
-    do_load         \bpp, 8
-      vmovn.u16       d20, q10     /* d20 = y */
-    vmovl.u8        q2, d1\r_offs  /* r = { d4, d5 } */
-      vmovn.u16       d21, q11     /* d21 = u */
-    vmovl.u8        q3, d1\g_offs  /* g = { d6, d7 } */
-      vmovn.u16       d22, q12     /* d22 = v */
-    vmovl.u8        q4, d1\b_offs  /* b = { d8, d9 } */
-    vmull.u16       q7, d4, d0[0]
-    vmlal.u16       q7, d6, d0[1]
-    vmlal.u16       q7, d8, d0[2]
-      vst1.8          {d20}, [Y]!
-    vmull.u16       q8, d5, d0[0]
-    vmlal.u16       q8, d7, d0[1]
-    vmlal.u16       q8, d9, d0[2]
-    vmlsl.u16       q9, d4, d0[3]
-    vmlsl.u16       q9, d6, d1[0]
-    vmlal.u16       q9, d8, d1[1]
-      vst1.8          {d21}, [U]!
-    vmlsl.u16       q13, d5, d0[3]
-    vmlsl.u16       q13, d7, d1[0]
-    vmlal.u16       q13, d9, d1[1]
-    vrev64.32       q14, q1
-    vrev64.32       q15, q1
-    vmlal.u16       q14, d4, d1[1]
-    vmlsl.u16       q14, d6, d1[2]
-    vmlsl.u16       q14, d8, d1[3]
-      vst1.8          {d22}, [V]!
-    vmlal.u16       q15, d5, d1[1]
-    vmlsl.u16       q15, d7, d1[2]
-    vmlsl.u16       q15, d9, d1[3]
-.endm
-
-.balign 16
-jsimd_\colorid\()_ycc_neon_consts:
-  .short 19595, 38470, 7471,  11059
-  .short 21709, 32768, 27439, 5329
-  .short 32767, 128,   32767, 128
-  .short 32767, 128,   32767, 128
-
-asm_function jsimd_\colorid\()_ycc_convert_neon
-    OUTPUT_WIDTH    .req r0
-    INPUT_BUF       .req r1
-    OUTPUT_BUF      .req r2
-    OUTPUT_ROW      .req r3
-    NUM_ROWS        .req r4
-
-    OUTPUT_BUF0     .req r5
-    OUTPUT_BUF1     .req r6
-    OUTPUT_BUF2     .req OUTPUT_BUF
-
-    RGB             .req r7
-    Y               .req r8
-    U               .req r9
-    V               .req r10
-    N               .req ip
-
-    /* Load constants to d0, d1, d2, d3 */
-    adr             ip, jsimd_\colorid\()_ycc_neon_consts
-    vld1.16         {d0, d1, d2, d3}, [ip, :128]
-
-    /* Save ARM registers and handle input arguments */
-    push            {r4, r5, r6, r7, r8, r9, r10, lr}
-    ldr             NUM_ROWS, [sp, #(4 * 8)]
-    ldr             OUTPUT_BUF0, [OUTPUT_BUF]
-    ldr             OUTPUT_BUF1, [OUTPUT_BUF, #4]
-    ldr             OUTPUT_BUF2, [OUTPUT_BUF, #8]
-    .unreq          OUTPUT_BUF
-
-    /* Save NEON registers */
-    vpush           {d8-d15}
-
-    /* Outer loop over scanlines */
-    cmp             NUM_ROWS, #1
-    blt             9f
-0:
-    ldr             Y, [OUTPUT_BUF0, OUTPUT_ROW, lsl #2]
-    ldr             U, [OUTPUT_BUF1, OUTPUT_ROW, lsl #2]
-    mov             N, OUTPUT_WIDTH
-    ldr             V, [OUTPUT_BUF2, OUTPUT_ROW, lsl #2]
-    add             OUTPUT_ROW, OUTPUT_ROW, #1
-    ldr             RGB, [INPUT_BUF], #4
-
-    /* Inner loop over pixels */
-    subs            N, N, #8
-    blt             3f
-    do_load         \bpp, 8
-    do_rgb_to_yuv_stage1
-    subs            N, N, #8
-    blt             2f
-1:
-    do_rgb_to_yuv_stage2_store_load_stage1
-    subs            N, N, #8
-    bge             1b
-2:
-    do_rgb_to_yuv_stage2
-    do_store        8
-    tst             N, #7
-    beq             8f
-3:
-    tst             N, #4
-    beq             3f
-    do_load         \bpp, 4
-3:
-    tst             N, #2
-    beq             4f
-    do_load         \bpp, 2
-4:
-    tst             N, #1
-    beq             5f
-    do_load         \bpp, 1
-5:
-    do_rgb_to_yuv
-    tst             N, #4
-    beq             6f
-    do_store        4
-6:
-    tst             N, #2
-    beq             7f
-    do_store        2
-7:
-    tst             N, #1
-    beq             8f
-    do_store        1
-8:
-    subs            NUM_ROWS, NUM_ROWS, #1
-    bgt             0b
-9:
-    /* Restore all registers and return */
-    vpop            {d8-d15}
-    pop             {r4, r5, r6, r7, r8, r9, r10, pc}
-
-    .unreq          OUTPUT_WIDTH
-    .unreq          OUTPUT_ROW
-    .unreq          INPUT_BUF
-    .unreq          NUM_ROWS
-    .unreq          OUTPUT_BUF0
-    .unreq          OUTPUT_BUF1
-    .unreq          OUTPUT_BUF2
-    .unreq          RGB
-    .unreq          Y
-    .unreq          U
-    .unreq          V
-    .unreq          N
-
-.purgem do_rgb_to_yuv
-.purgem do_rgb_to_yuv_stage1
-.purgem do_rgb_to_yuv_stage2
-.purgem do_rgb_to_yuv_stage2_store_load_stage1
-
-.endm
-
-/*--------------------------------- id ----- bpp R  G  B */
-generate_jsimd_rgb_ycc_convert_neon extrgb,  24, 0, 1, 2
-generate_jsimd_rgb_ycc_convert_neon extbgr,  24, 2, 1, 0
-generate_jsimd_rgb_ycc_convert_neon extrgbx, 32, 0, 1, 2
-generate_jsimd_rgb_ycc_convert_neon extbgrx, 32, 2, 1, 0
-generate_jsimd_rgb_ycc_convert_neon extxbgr, 32, 3, 2, 1
-generate_jsimd_rgb_ycc_convert_neon extxrgb, 32, 1, 2, 3
-
-.purgem do_load
-.purgem do_store
-
-
-/*****************************************************************************/
-
-/*
- * Load data into workspace, applying unsigned->signed conversion
- *
- * TODO: can be combined with 'jsimd_fdct_ifast_neon' to get
- *       rid of VST1.16 instructions
- */
-
-asm_function jsimd_convsamp_neon
-    SAMPLE_DATA     .req r0
-    START_COL       .req r1
-    WORKSPACE       .req r2
-    TMP1            .req r3
-    TMP2            .req r4
-    TMP3            .req r5
-    TMP4            .req ip
-
-    push            {r4, r5}
-    vmov.u8         d0, #128
-
-    ldmia           SAMPLE_DATA!, {TMP1, TMP2, TMP3, TMP4}
-    add             TMP1, TMP1, START_COL
-    add             TMP2, TMP2, START_COL
-    add             TMP3, TMP3, START_COL
-    add             TMP4, TMP4, START_COL
-    vld1.8          {d16}, [TMP1]
-    vsubl.u8        q8, d16, d0
-    vld1.8          {d18}, [TMP2]
-    vsubl.u8        q9, d18, d0
-    vld1.8          {d20}, [TMP3]
-    vsubl.u8        q10, d20, d0
-    vld1.8          {d22}, [TMP4]
-    ldmia           SAMPLE_DATA!, {TMP1, TMP2, TMP3, TMP4}
-    vsubl.u8        q11, d22, d0
-    vst1.16         {d16, d17, d18, d19}, [WORKSPACE, :128]!
-    add             TMP1, TMP1, START_COL
-    add             TMP2, TMP2, START_COL
-    vst1.16         {d20, d21, d22, d23}, [WORKSPACE, :128]!
-    add             TMP3, TMP3, START_COL
-    add             TMP4, TMP4, START_COL
-    vld1.8          {d24}, [TMP1]
-    vsubl.u8        q12, d24, d0
-    vld1.8          {d26}, [TMP2]
-    vsubl.u8        q13, d26, d0
-    vld1.8          {d28}, [TMP3]
-    vsubl.u8        q14, d28, d0
-    vld1.8          {d30}, [TMP4]
-    vsubl.u8        q15, d30, d0
-    vst1.16         {d24, d25, d26, d27}, [WORKSPACE, :128]!
-    vst1.16         {d28, d29, d30, d31}, [WORKSPACE, :128]!
-    pop             {r4, r5}
-    bx              lr
-
-    .unreq          SAMPLE_DATA
-    .unreq          START_COL
-    .unreq          WORKSPACE
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_fdct_ifast_neon
- *
- * This function contains a fast, not so accurate integer implementation of
- * the forward DCT (Discrete Cosine Transform). It uses the same calculations
- * and produces exactly the same output as IJG's original 'jpeg_fdct_ifast'
- * function from jfdctfst.c
- *
- * TODO: can be combined with 'jsimd_convsamp_neon' to get
- *       rid of a bunch of VLD1.16 instructions
- */
-
-#define XFIX_0_382683433  d0[0]
-#define XFIX_0_541196100  d0[1]
-#define XFIX_0_707106781  d0[2]
-#define XFIX_1_306562965  d0[3]
-
-.balign 16
-jsimd_fdct_ifast_neon_consts:
-  .short (98 * 128)               /* XFIX_0_382683433 */
-  .short (139 * 128)              /* XFIX_0_541196100 */
-  .short (181 * 128)              /* XFIX_0_707106781 */
-  .short (334 * 128 - 256 * 128)  /* XFIX_1_306562965 */
-
-asm_function jsimd_fdct_ifast_neon
-
-    DATA            .req r0
-    TMP             .req ip
-
-    vpush           {d8-d15}
-
-    /* Load constants */
-    adr             TMP, jsimd_fdct_ifast_neon_consts
-    vld1.16         {d0}, [TMP, :64]
-
-    /* Load all DATA into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17    | q8
-     *   1 | d18     | d19    | q9
-     *   2 | d20     | d21    | q10
-     *   3 | d22     | d23    | q11
-     *   4 | d24     | d25    | q12
-     *   5 | d26     | d27    | q13
-     *   6 | d28     | d29    | q14
-     *   7 | d30     | d31    | q15
-     */
-
-    vld1.16         {d16, d17, d18, d19}, [DATA, :128]!
-    vld1.16         {d20, d21, d22, d23}, [DATA, :128]!
-    vld1.16         {d24, d25, d26, d27}, [DATA, :128]!
-    vld1.16         {d28, d29, d30, d31}, [DATA, :128]
-    sub             DATA, DATA, #(128 - 32)
-
-    mov             TMP, #2
-1:
-    /* Transpose */
-    vtrn.16         q12, q13
-    vtrn.16         q10, q11
-    vtrn.16         q8, q9
-    vtrn.16         q14, q15
-    vtrn.32         q9, q11
-    vtrn.32         q13, q15
-    vtrn.32         q8, q10
-    vtrn.32         q12, q14
-    vswp            d30, d23
-    vswp            d24, d17
-    vswp            d26, d19
-      /* 1-D FDCT */
-      vadd.s16        q2, q11, q12
-    vswp            d28, d21
-      vsub.s16        q12, q11, q12
-      vsub.s16        q6, q10, q13
-      vadd.s16        q10, q10, q13
-      vsub.s16        q7, q9, q14
-      vadd.s16        q9, q9, q14
-      vsub.s16        q1, q8, q15
-      vadd.s16        q8, q8, q15
-      vsub.s16        q4, q9, q10
-      vsub.s16        q5, q8, q2
-      vadd.s16        q3, q9, q10
-      vadd.s16        q4, q4, q5
-      vadd.s16        q2, q8, q2
-      vqdmulh.s16     q4, q4, XFIX_0_707106781
-      vadd.s16        q11, q12, q6
-      vadd.s16        q8, q2, q3
-      vsub.s16        q12, q2, q3
-      vadd.s16        q3, q6, q7
-      vadd.s16        q7, q7, q1
-      vqdmulh.s16     q3, q3, XFIX_0_707106781
-      vsub.s16        q6, q11, q7
-      vadd.s16        q10, q5, q4
-      vqdmulh.s16     q6, q6, XFIX_0_382683433
-      vsub.s16        q14, q5, q4
-      vqdmulh.s16     q11, q11, XFIX_0_541196100
-      vqdmulh.s16     q5, q7, XFIX_1_306562965
-      vadd.s16        q4, q1, q3
-      vsub.s16        q3, q1, q3
-      vadd.s16        q7, q7, q6
-      vadd.s16        q11, q11, q6
-      vadd.s16        q7, q7, q5
-      vadd.s16        q13, q3, q11
-      vsub.s16        q11, q3, q11
-      vadd.s16        q9, q4, q7
-      vsub.s16        q15, q4, q7
-    subs            TMP, TMP, #1
-    bne             1b
-
-    /* store results */
-    vst1.16         {d16, d17, d18, d19}, [DATA, :128]!
-    vst1.16         {d20, d21, d22, d23}, [DATA, :128]!
-    vst1.16         {d24, d25, d26, d27}, [DATA, :128]!
-    vst1.16         {d28, d29, d30, d31}, [DATA, :128]
-
-    vpop            {d8-d15}
-    bx              lr
-
-    .unreq          DATA
-    .unreq          TMP
-
-
-/*****************************************************************************/
-
-/*
- * GLOBAL(void)
- * jsimd_quantize_neon(JCOEFPTR coef_block, DCTELEM *divisors,
- *                     DCTELEM *workspace);
- *
- * Note: the code uses 2 stage pipelining in order to improve instructions
- *       scheduling and eliminate stalls (this provides ~15% better
- *       performance for this function on both ARM Cortex-A8 and
- *       ARM Cortex-A9 when compared to the non-pipelined variant).
- *       The instructions which belong to the second stage use different
- *       indentation for better readiability.
- */
-asm_function jsimd_quantize_neon
-
-    COEF_BLOCK      .req r0
-    DIVISORS        .req r1
-    WORKSPACE       .req r2
-
-    RECIPROCAL      .req DIVISORS
-    CORRECTION      .req r3
-    SHIFT           .req ip
-    LOOP_COUNT      .req r4
-
-    vld1.16         {d0, d1, d2, d3}, [WORKSPACE, :128]!
-    vabs.s16        q12, q0
-    add             CORRECTION, DIVISORS, #(64 * 2)
-    add             SHIFT, DIVISORS, #(64 * 6)
-    vld1.16         {d20, d21, d22, d23}, [CORRECTION, :128]!
-    vabs.s16        q13, q1
-    vld1.16         {d16, d17, d18, d19}, [RECIPROCAL, :128]!
-    vadd.u16        q12, q12, q10  /* add correction */
-    vadd.u16        q13, q13, q11
-    vmull.u16       q10, d24, d16  /* multiply by reciprocal */
-    vmull.u16       q11, d25, d17
-    vmull.u16       q8, d26, d18
-    vmull.u16       q9, d27, d19
-    vld1.16         {d24, d25, d26, d27}, [SHIFT, :128]!
-    vshrn.u32       d20, q10, #16
-    vshrn.u32       d21, q11, #16
-    vshrn.u32       d22, q8, #16
-    vshrn.u32       d23, q9, #16
-    vneg.s16        q12, q12
-    vneg.s16        q13, q13
-    vshr.s16        q2, q0, #15    /* extract sign */
-    vshr.s16        q3, q1, #15
-    vshl.u16        q14, q10, q12  /* shift */
-    vshl.u16        q15, q11, q13
-
-    push            {r4, r5}
-    mov             LOOP_COUNT, #3
-1:
-    vld1.16         {d0, d1, d2, d3}, [WORKSPACE, :128]!
-      veor.u16        q14, q14, q2  /* restore sign */
-    vabs.s16        q12, q0
-    vld1.16         {d20, d21, d22, d23}, [CORRECTION, :128]!
-    vabs.s16        q13, q1
-      veor.u16        q15, q15, q3
-    vld1.16         {d16, d17, d18, d19}, [RECIPROCAL, :128]!
-    vadd.u16        q12, q12, q10  /* add correction */
-    vadd.u16        q13, q13, q11
-    vmull.u16       q10, d24, d16  /* multiply by reciprocal */
-    vmull.u16       q11, d25, d17
-    vmull.u16       q8, d26, d18
-    vmull.u16       q9, d27, d19
-      vsub.u16        q14, q14, q2
-    vld1.16         {d24, d25, d26, d27}, [SHIFT, :128]!
-      vsub.u16        q15, q15, q3
-    vshrn.u32       d20, q10, #16
-    vshrn.u32       d21, q11, #16
-      vst1.16         {d28, d29, d30, d31}, [COEF_BLOCK, :128]!
-    vshrn.u32       d22, q8, #16
-    vshrn.u32       d23, q9, #16
-    vneg.s16        q12, q12
-    vneg.s16        q13, q13
-    vshr.s16        q2, q0, #15    /* extract sign */
-    vshr.s16        q3, q1, #15
-    vshl.u16        q14, q10, q12  /* shift */
-    vshl.u16        q15, q11, q13
-    subs            LOOP_COUNT, LOOP_COUNT, #1
-    bne             1b
-    pop             {r4, r5}
-
-      veor.u16        q14, q14, q2  /* restore sign */
-      veor.u16        q15, q15, q3
-      vsub.u16        q14, q14, q2
-      vsub.u16        q15, q15, q3
-      vst1.16         {d28, d29, d30, d31}, [COEF_BLOCK, :128]!
-
-    bx              lr  /* return */
-
-    .unreq          COEF_BLOCK
-    .unreq          DIVISORS
-    .unreq          WORKSPACE
-    .unreq          RECIPROCAL
-    .unreq          CORRECTION
-    .unreq          SHIFT
-    .unreq          LOOP_COUNT
-
-
-/*****************************************************************************/
-
-/*
- * GLOBAL(void)
- * jsimd_h2v1_fancy_upsample_neon(int max_v_samp_factor,
- *                                JDIMENSION downsampled_width,
- *                                JSAMPARRAY input_data,
- *                                JSAMPARRAY *output_data_ptr);
- *
- * Note: the use of unaligned writes is the main remaining bottleneck in
- *       this code, which can be potentially solved to get up to tens
- *       of percents performance improvement on Cortex-A8/Cortex-A9.
- */
-
-/*
- * Upsample 16 source pixels to 32 destination pixels. The new 16 source
- * pixels are loaded to q0. The previous 16 source pixels are in q1. The
- * shifted-by-one source pixels are constructed in q2 by using q0 and q1.
- * Register d28 is used for multiplication by 3. Register q15 is used
- * for adding +1 bias.
- */
-.macro upsample16 OUTPTR, INPTR
-    vld1.8          {q0}, [\INPTR]!
-    vmovl.u8        q8, d0
-    vext.8          q2, q1, q0, #15
-    vmovl.u8        q9, d1
-    vaddw.u8        q10, q15, d4
-    vaddw.u8        q11, q15, d5
-    vmlal.u8        q8, d4, d28
-    vmlal.u8        q9, d5, d28
-    vmlal.u8        q10, d0, d28
-    vmlal.u8        q11, d1, d28
-    vmov            q1, q0        /* backup source pixels to q1 */
-    vrshrn.u16      d6, q8, #2
-    vrshrn.u16      d7, q9, #2
-    vshrn.u16       d8, q10, #2
-    vshrn.u16       d9, q11, #2
-    vst2.8          {d6, d7, d8, d9}, [\OUTPTR]!
-.endm
-
-/*
- * Upsample 32 source pixels to 64 destination pixels. Compared to 'usample16'
- * macro, the roles of q0 and q1 registers are reversed for even and odd
- * groups of 16 pixels, that's why "vmov q1, q0" instructions are not needed.
- * Also this unrolling allows to reorder loads and stores to compensate
- * multiplication latency and reduce stalls.
- */
-.macro upsample32 OUTPTR, INPTR
-    /* even 16 pixels group */
-    vld1.8          {q0}, [\INPTR]!
-    vmovl.u8        q8, d0
-    vext.8          q2, q1, q0, #15
-    vmovl.u8        q9, d1
-    vaddw.u8        q10, q15, d4
-    vaddw.u8        q11, q15, d5
-    vmlal.u8        q8, d4, d28
-    vmlal.u8        q9, d5, d28
-    vmlal.u8        q10, d0, d28
-    vmlal.u8        q11, d1, d28
-      /* odd 16 pixels group */
-      vld1.8          {q1}, [\INPTR]!
-    vrshrn.u16      d6, q8, #2
-    vrshrn.u16      d7, q9, #2
-    vshrn.u16       d8, q10, #2
-    vshrn.u16       d9, q11, #2
-      vmovl.u8        q8, d2
-      vext.8          q2, q0, q1, #15
-      vmovl.u8        q9, d3
-      vaddw.u8        q10, q15, d4
-      vaddw.u8        q11, q15, d5
-      vmlal.u8        q8, d4, d28
-      vmlal.u8        q9, d5, d28
-      vmlal.u8        q10, d2, d28
-      vmlal.u8        q11, d3, d28
-    vst2.8          {d6, d7, d8, d9}, [\OUTPTR]!
-      vrshrn.u16      d6, q8, #2
-      vrshrn.u16      d7, q9, #2
-      vshrn.u16       d8, q10, #2
-      vshrn.u16       d9, q11, #2
-      vst2.8          {d6, d7, d8, d9}, [\OUTPTR]!
-.endm
-
-/*
- * Upsample a row of WIDTH pixels from INPTR to OUTPTR.
- */
-.macro upsample_row OUTPTR, INPTR, WIDTH, TMP1
-    /* special case for the first and last pixels */
-    sub             \WIDTH, \WIDTH, #1
-    add             \OUTPTR, \OUTPTR, #1
-    ldrb            \TMP1, [\INPTR, \WIDTH]
-    strb            \TMP1, [\OUTPTR, \WIDTH, asl #1]
-    ldrb            \TMP1, [\INPTR], #1
-    strb            \TMP1, [\OUTPTR, #-1]
-    vmov.8          d3[7], \TMP1
-
-    subs            \WIDTH, \WIDTH, #32
-    blt             5f
-0:  /* process 32 pixels per iteration */
-    upsample32      \OUTPTR, \INPTR
-    subs            \WIDTH, \WIDTH, #32
-    bge             0b
-5:
-    adds            \WIDTH, \WIDTH, #16
-    blt             1f
-0:  /* process 16 pixels if needed */
-    upsample16      \OUTPTR, \INPTR
-    subs            \WIDTH, \WIDTH, #16
-1:
-    adds            \WIDTH, \WIDTH, #16
-    beq             9f
-
-    /* load the remaining 1-15 pixels */
-    add             \INPTR, \INPTR, \WIDTH
-    tst             \WIDTH, #1
-    beq             2f
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[0]}, [\INPTR]
-2:
-    tst             \WIDTH, #2
-    beq             2f
-    vext.8          d0, d0, d0, #6
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[1]}, [\INPTR]
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[0]}, [\INPTR]
-2:
-    tst             \WIDTH, #4
-    beq             2f
-    vrev64.32       d0, d0
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[3]}, [\INPTR]
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[2]}, [\INPTR]
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[1]}, [\INPTR]
-    sub             \INPTR, \INPTR, #1
-    vld1.8          {d0[0]}, [\INPTR]
-2:
-    tst             \WIDTH, #8
-    beq             2f
-    vmov            d1, d0
-    sub             \INPTR, \INPTR, #8
-    vld1.8          {d0}, [\INPTR]
-2:  /* upsample the remaining pixels */
-    vmovl.u8        q8, d0
-    vext.8          q2, q1, q0, #15
-    vmovl.u8        q9, d1
-    vaddw.u8        q10, q15, d4
-    vaddw.u8        q11, q15, d5
-    vmlal.u8        q8, d4, d28
-    vmlal.u8        q9, d5, d28
-    vmlal.u8        q10, d0, d28
-    vmlal.u8        q11, d1, d28
-    vrshrn.u16      d10, q8, #2
-    vrshrn.u16      d12, q9, #2
-    vshrn.u16       d11, q10, #2
-    vshrn.u16       d13, q11, #2
-    vzip.8          d10, d11
-    vzip.8          d12, d13
-    /* store the remaining pixels */
-    tst             \WIDTH, #8
-    beq             2f
-    vst1.8          {d10, d11}, [\OUTPTR]!
-    vmov            q5, q6
-2:
-    tst             \WIDTH, #4
-    beq             2f
-    vst1.8          {d10}, [\OUTPTR]!
-    vmov            d10, d11
-2:
-    tst             \WIDTH, #2
-    beq             2f
-    vst1.8          {d10[0]}, [\OUTPTR]!
-    vst1.8          {d10[1]}, [\OUTPTR]!
-    vst1.8          {d10[2]}, [\OUTPTR]!
-    vst1.8          {d10[3]}, [\OUTPTR]!
-    vext.8          d10, d10, d10, #4
-2:
-    tst             \WIDTH, #1
-    beq             2f
-    vst1.8          {d10[0]}, [\OUTPTR]!
-    vst1.8          {d10[1]}, [\OUTPTR]!
-2:
-9:
-.endm
-
-asm_function jsimd_h2v1_fancy_upsample_neon
-
-    MAX_V_SAMP_FACTOR .req r0
-    DOWNSAMPLED_WIDTH .req r1
-    INPUT_DATA        .req r2
-    OUTPUT_DATA_PTR   .req r3
-    OUTPUT_DATA       .req OUTPUT_DATA_PTR
-
-    OUTPTR            .req r4
-    INPTR             .req r5
-    WIDTH             .req ip
-    TMP               .req lr
-
-    push            {r4, r5, r6, lr}
-    vpush           {d8-d15}
-
-    ldr             OUTPUT_DATA, [OUTPUT_DATA_PTR]
-    cmp             MAX_V_SAMP_FACTOR, #0
-    ble             99f
-
-    /* initialize constants */
-    vmov.u8         d28, #3
-    vmov.u16        q15, #1
-11:
-    ldr             INPTR, [INPUT_DATA], #4
-    ldr             OUTPTR, [OUTPUT_DATA], #4
-    mov             WIDTH, DOWNSAMPLED_WIDTH
-    upsample_row    OUTPTR, INPTR, WIDTH, TMP
-    subs            MAX_V_SAMP_FACTOR, MAX_V_SAMP_FACTOR, #1
-    bgt             11b
-
-99:
-    vpop            {d8-d15}
-    pop             {r4, r5, r6, pc}
-
-    .unreq          MAX_V_SAMP_FACTOR
-    .unreq          DOWNSAMPLED_WIDTH
-    .unreq          INPUT_DATA
-    .unreq          OUTPUT_DATA_PTR
-    .unreq          OUTPUT_DATA
-
-    .unreq          OUTPTR
-    .unreq          INPTR
-    .unreq          WIDTH
-    .unreq          TMP
-
-.purgem upsample16
-.purgem upsample32
-.purgem upsample_row
-
-
-/*****************************************************************************/
-
-/*
- * GLOBAL(JOCTET *)
- * jsimd_huff_encode_one_block(working_state *state, JOCTET *buffer,
- *                             JCOEFPTR block, int last_dc_val,
- *                             c_derived_tbl *dctbl, c_derived_tbl *actbl)
- *
- */
-
-.macro emit_byte BUFFER, PUT_BUFFER, PUT_BITS, ZERO, TMP
-    sub             \PUT_BITS, \PUT_BITS, #0x8
-    lsr             \TMP, \PUT_BUFFER, \PUT_BITS
-    uxtb            \TMP, \TMP
-    strb            \TMP, [\BUFFER, #1]!
-    cmp             \TMP, #0xff
-    /*it eq*/
-    strbeq          \ZERO, [\BUFFER, #1]!
-.endm
-
-.macro put_bits PUT_BUFFER, PUT_BITS, CODE, SIZE
-    /*lsl             \PUT_BUFFER, \PUT_BUFFER, \SIZE*/
-    add             \PUT_BITS, \SIZE
-    /*orr             \PUT_BUFFER, \PUT_BUFFER, \CODE*/
-    orr             \PUT_BUFFER, \CODE, \PUT_BUFFER, lsl \SIZE
-.endm
-
-.macro checkbuf15 BUFFER, PUT_BUFFER, PUT_BITS, ZERO, TMP
-  cmp               \PUT_BITS, #0x10
-  blt               15f
-    eor               \ZERO, \ZERO, \ZERO
-    emit_byte         \BUFFER, \PUT_BUFFER, \PUT_BITS, \ZERO, \TMP
-    emit_byte         \BUFFER, \PUT_BUFFER, \PUT_BITS, \ZERO, \TMP
-15:
-.endm
-
-.balign 16
-jsimd_huff_encode_one_block_neon_consts:
-  .byte 0x01
-  .byte 0x02
-  .byte 0x04
-  .byte 0x08
-  .byte 0x10
-  .byte 0x20
-  .byte 0x40
-  .byte 0x80
-
-asm_function jsimd_huff_encode_one_block_neon
-    push            {r4, r5, r6, r7, r8, r9, r10, r11, lr}
-    add             r7, sp, #0x1c
-    sub             r4, sp, #0x40
-    bfc             r4, #0, #5
-    mov             sp, r4           /* align sp on 32 bytes */
-    vst1.64         {d8, d9, d10, d11}, [r4, :128]!
-    vst1.64         {d12, d13, d14, d15}, [r4, :128]
-    sub             sp, #0x140       /* reserve 320 bytes */
-    str             r0, [sp, #0x18]  /* working state > sp + Ox18 */
-    add             r4, sp, #0x20    /* r4 = t1 */
-    ldr             lr, [r7, #0x8]   /* lr = dctbl */
-    sub             r10, r1, #0x1    /* r10=buffer-- */
-    ldrsh           r1, [r2]
-    mov             r9, #0x10
-    mov             r8, #0x1
-    adr             r5, jsimd_huff_encode_one_block_neon_consts
-    /* prepare data */
-    vld1.8          {d26}, [r5, :64]
-    veor            q8, q8, q8
-    veor            q9, q9, q9
-    vdup.16         q14, r9
-    vdup.16         q15, r8
-    veor            q10, q10, q10
-    veor            q11, q11, q11
-    sub             r1, r1, r3
-    add             r9, r2, #0x22
-    add             r8, r2, #0x18
-    add             r3, r2, #0x36
-    vmov.16         d0[0], r1
-    vld1.16         {d2[0]}, [r9, :16]
-    vld1.16         {d4[0]}, [r8, :16]
-    vld1.16         {d6[0]}, [r3, :16]
-    add             r1, r2, #0x2
-    add             r9, r2, #0x30
-    add             r8, r2, #0x26
-    add             r3, r2, #0x28
-    vld1.16         {d0[1]}, [r1, :16]
-    vld1.16         {d2[1]}, [r9, :16]
-    vld1.16         {d4[1]}, [r8, :16]
-    vld1.16         {d6[1]}, [r3, :16]
-    add             r1, r2, #0x10
-    add             r9, r2, #0x40
-    add             r8, r2, #0x34
-    add             r3, r2, #0x1a
-    vld1.16         {d0[2]}, [r1, :16]
-    vld1.16         {d2[2]}, [r9, :16]
-    vld1.16         {d4[2]}, [r8, :16]
-    vld1.16         {d6[2]}, [r3, :16]
-    add             r1, r2, #0x20
-    add             r9, r2, #0x32
-    add             r8, r2, #0x42
-    add             r3, r2, #0xc
-    vld1.16         {d0[3]}, [r1, :16]
-    vld1.16         {d2[3]}, [r9, :16]
-    vld1.16         {d4[3]}, [r8, :16]
-    vld1.16         {d6[3]}, [r3, :16]
-    add             r1, r2, #0x12
-    add             r9, r2, #0x24
-    add             r8, r2, #0x50
-    add             r3, r2, #0xe
-    vld1.16         {d1[0]}, [r1, :16]
-    vld1.16         {d3[0]}, [r9, :16]
-    vld1.16         {d5[0]}, [r8, :16]
-    vld1.16         {d7[0]}, [r3, :16]
-    add             r1, r2, #0x4
-    add             r9, r2, #0x16
-    add             r8, r2, #0x60
-    add             r3, r2, #0x1c
-    vld1.16         {d1[1]}, [r1, :16]
-    vld1.16         {d3[1]}, [r9, :16]
-    vld1.16         {d5[1]}, [r8, :16]
-    vld1.16         {d7[1]}, [r3, :16]
-    add             r1, r2, #0x6
-    add             r9, r2, #0x8
-    add             r8, r2, #0x52
-    add             r3, r2, #0x2a
-    vld1.16         {d1[2]}, [r1, :16]
-    vld1.16         {d3[2]}, [r9, :16]
-    vld1.16         {d5[2]}, [r8, :16]
-    vld1.16         {d7[2]}, [r3, :16]
-    add             r1, r2, #0x14
-    add             r9, r2, #0xa
-    add             r8, r2, #0x44
-    add             r3, r2, #0x38
-    vld1.16         {d1[3]}, [r1, :16]
-    vld1.16         {d3[3]}, [r9, :16]
-    vld1.16         {d5[3]}, [r8, :16]
-    vld1.16         {d7[3]}, [r3, :16]
-    vcgt.s16        q8, q8, q0
-    vcgt.s16        q9, q9, q1
-    vcgt.s16        q10, q10, q2
-    vcgt.s16        q11, q11, q3
-    vabs.s16        q0, q0
-    vabs.s16        q1, q1
-    vabs.s16        q2, q2
-    vabs.s16        q3, q3
-    veor            q8, q8, q0
-    veor            q9, q9, q1
-    veor            q10, q10, q2
-    veor            q11, q11, q3
-    add             r9, r4, #0x20
-    add             r8, r4, #0x80
-    add             r3, r4, #0xa0
-    vclz.i16        q0, q0
-    vclz.i16        q1, q1
-    vclz.i16        q2, q2
-    vclz.i16        q3, q3
-    vsub.i16        q0, q14, q0
-    vsub.i16        q1, q14, q1
-    vsub.i16        q2, q14, q2
-    vsub.i16        q3, q14, q3
-    vst1.16         {d0, d1, d2, d3}, [r4, :256]
-    vst1.16         {d4, d5, d6, d7}, [r9, :256]
-    vshl.s16        q0, q15, q0
-    vshl.s16        q1, q15, q1
-    vshl.s16        q2, q15, q2
-    vshl.s16        q3, q15, q3
-    vsub.i16        q0, q0, q15
-    vsub.i16        q1, q1, q15
-    vsub.i16        q2, q2, q15
-    vsub.i16        q3, q3, q15
-    vand            q8, q8, q0
-    vand            q9, q9, q1
-    vand            q10, q10, q2
-    vand            q11, q11, q3
-    vst1.16         {d16, d17, d18, d19}, [r8, :256]
-    vst1.16         {d20, d21, d22, d23}, [r3, :256]
-    add             r1, r2, #0x46
-    add             r9, r2, #0x3a
-    add             r8, r2, #0x74
-    add             r3, r2, #0x6a
-    vld1.16         {d8[0]}, [r1, :16]
-    vld1.16         {d10[0]}, [r9, :16]
-    vld1.16         {d12[0]}, [r8, :16]
-    vld1.16         {d14[0]}, [r3, :16]
-    veor            q8, q8, q8
-    veor            q9, q9, q9
-    veor            q10, q10, q10
-    veor            q11, q11, q11
-    add             r1, r2, #0x54
-    add             r9, r2, #0x2c
-    add             r8, r2, #0x76
-    add             r3, r2, #0x78
-    vld1.16         {d8[1]}, [r1, :16]
-    vld1.16         {d10[1]}, [r9, :16]
-    vld1.16         {d12[1]}, [r8, :16]
-    vld1.16         {d14[1]}, [r3, :16]
-    add             r1, r2, #0x62
-    add             r9, r2, #0x1e
-    add             r8, r2, #0x68
-    add             r3, r2, #0x7a
-    vld1.16         {d8[2]}, [r1, :16]
-    vld1.16         {d10[2]}, [r9, :16]
-    vld1.16         {d12[2]}, [r8, :16]
-    vld1.16         {d14[2]}, [r3, :16]
-    add             r1, r2, #0x70
-    add             r9, r2, #0x2e
-    add             r8, r2, #0x5a
-    add             r3, r2, #0x6c
-    vld1.16         {d8[3]}, [r1, :16]
-    vld1.16         {d10[3]}, [r9, :16]
-    vld1.16         {d12[3]}, [r8, :16]
-    vld1.16         {d14[3]}, [r3, :16]
-    add             r1, r2, #0x72
-    add             r9, r2, #0x3c
-    add             r8, r2, #0x4c
-    add             r3, r2, #0x5e
-    vld1.16         {d9[0]}, [r1, :16]
-    vld1.16         {d11[0]}, [r9, :16]
-    vld1.16         {d13[0]}, [r8, :16]
-    vld1.16         {d15[0]}, [r3, :16]
-    add             r1, r2, #0x64
-    add             r9, r2, #0x4a
-    add             r8, r2, #0x3e
-    add             r3, r2, #0x6e
-    vld1.16         {d9[1]}, [r1, :16]
-    vld1.16         {d11[1]}, [r9, :16]
-    vld1.16         {d13[1]}, [r8, :16]
-    vld1.16         {d15[1]}, [r3, :16]
-    add             r1, r2, #0x56
-    add             r9, r2, #0x58
-    add             r8, r2, #0x4e
-    add             r3, r2, #0x7c
-    vld1.16         {d9[2]}, [r1, :16]
-    vld1.16         {d11[2]}, [r9, :16]
-    vld1.16         {d13[2]}, [r8, :16]
-    vld1.16         {d15[2]}, [r3, :16]
-    add             r1, r2, #0x48
-    add             r9, r2, #0x66
-    add             r8, r2, #0x5c
-    add             r3, r2, #0x7e
-    vld1.16         {d9[3]}, [r1, :16]
-    vld1.16         {d11[3]}, [r9, :16]
-    vld1.16         {d13[3]}, [r8, :16]
-    vld1.16         {d15[3]}, [r3, :16]
-    vcgt.s16        q8, q8, q4
-    vcgt.s16        q9, q9, q5
-    vcgt.s16        q10, q10, q6
-    vcgt.s16        q11, q11, q7
-    vabs.s16        q4, q4
-    vabs.s16        q5, q5
-    vabs.s16        q6, q6
-    vabs.s16        q7, q7
-    veor            q8, q8, q4
-    veor            q9, q9, q5
-    veor            q10, q10, q6
-    veor            q11, q11, q7
-    add             r1, r4, #0x40
-    add             r9, r4, #0x60
-    add             r8, r4, #0xc0
-    add             r3, r4, #0xe0
-    vclz.i16        q4, q4
-    vclz.i16        q5, q5
-    vclz.i16        q6, q6
-    vclz.i16        q7, q7
-    vsub.i16        q4, q14, q4
-    vsub.i16        q5, q14, q5
-    vsub.i16        q6, q14, q6
-    vsub.i16        q7, q14, q7
-    vst1.16         {d8, d9, d10, d11}, [r1, :256]
-    vst1.16         {d12, d13, d14, d15}, [r9, :256]
-    vshl.s16        q4, q15, q4
-    vshl.s16        q5, q15, q5
-    vshl.s16        q6, q15, q6
-    vshl.s16        q7, q15, q7
-    vsub.i16        q4, q4, q15
-    vsub.i16        q5, q5, q15
-    vsub.i16        q6, q6, q15
-    vsub.i16        q7, q7, q15
-    vand            q8, q8, q4
-    vand            q9, q9, q5
-    vand            q10, q10, q6
-    vand            q11, q11, q7
-    vst1.16         {d16, d17, d18, d19}, [r8, :256]
-    vst1.16         {d20, d21, d22, d23}, [r3, :256]
-    ldr             r12, [r7, #0xc]       /* r12 = actbl */
-    add             r1, lr, #0x400        /* r1 = dctbl->ehufsi */
-    mov             r9, r12               /* r9 = actbl */
-    add             r6, r4, #0x80         /* r6 = t2 */
-    ldr             r11, [r0, #0x8]       /* r11 = put_buffer */
-    ldr             r4, [r0, #0xc]        /* r4  = put_bits */
-    ldrh            r2, [r6, #-128]       /* r2  = nbits */
-    ldrh            r3, [r6]              /* r3  = temp2 & (((JLONG)1)<<nbits) - 1; */
-    ldr             r0, [lr, r2, lsl #2]
-    ldrb            r5, [r1, r2]
-    put_bits        r11, r4, r0, r5
-    checkbuf15      r10, r11, r4, r5, r0
-    put_bits        r11, r4, r3, r2
-    checkbuf15      r10, r11, r4, r5, r0
-    mov             lr, r6                /* lr = t2 */
-    add             r5, r9, #0x400        /* r5 = actbl->ehufsi */
-    ldrsb           r6, [r5, #0xf0]       /* r6 = actbl->ehufsi[0xf0] */
-    veor            q8, q8, q8
-    vceq.i16        q0, q0, q8
-    vceq.i16        q1, q1, q8
-    vceq.i16        q2, q2, q8
-    vceq.i16        q3, q3, q8
-    vceq.i16        q4, q4, q8
-    vceq.i16        q5, q5, q8
-    vceq.i16        q6, q6, q8
-    vceq.i16        q7, q7, q8
-    vmovn.i16       d0, q0
-    vmovn.i16       d2, q1
-    vmovn.i16       d4, q2
-    vmovn.i16       d6, q3
-    vmovn.i16       d8, q4
-    vmovn.i16       d10, q5
-    vmovn.i16       d12, q6
-    vmovn.i16       d14, q7
-    vand            d0, d0, d26
-    vand            d2, d2, d26
-    vand            d4, d4, d26
-    vand            d6, d6, d26
-    vand            d8, d8, d26
-    vand            d10, d10, d26
-    vand            d12, d12, d26
-    vand            d14, d14, d26
-    vpadd.i8        d0, d0, d2
-    vpadd.i8        d4, d4, d6
-    vpadd.i8        d8, d8, d10
-    vpadd.i8        d12, d12, d14
-    vpadd.i8        d0, d0, d4
-    vpadd.i8        d8, d8, d12
-    vpadd.i8        d0, d0, d8
-    vmov.32         r1, d0[1]
-    vmov.32         r8, d0[0]
-    mvn             r1, r1
-    mvn             r8, r8
-    lsrs            r1, r1, #0x1
-    rrx             r8, r8            /* shift in last r1 bit while shifting out DC bit */
-    rbit            r1, r1            /* r1 = index1 */
-    rbit            r8, r8            /* r8 = index0 */
-    ldr             r0, [r9, #0x3c0]  /* r0 = actbl->ehufco[0xf0] */
-    str             r1, [sp, #0x14]   /* index1 > sp + 0x14 */
-    cmp             r8, #0x0
-    beq             6f
-1:
-    clz             r2, r8
-    add             lr, lr, r2, lsl #1
-    lsl             r8, r8, r2
-    ldrh            r1, [lr, #-126]
-2:
-    cmp             r2, #0x10
-    blt             3f
-    sub             r2, r2, #0x10
-    put_bits        r11, r4, r0, r6
-    cmp             r4, #0x10
-    blt             2b
-    eor             r3, r3, r3
-    emit_byte       r10, r11, r4, r3, r12
-    emit_byte       r10, r11, r4, r3, r12
-    b               2b
-3:
-    add             r2, r1, r2, lsl #4
-    ldrh            r3, [lr, #2]!
-    ldr             r12, [r9, r2, lsl #2]
-    ldrb            r2, [r5, r2]
-    put_bits        r11, r4, r12, r2
-    checkbuf15      r10, r11, r4, r2, r12
-    put_bits        r11, r4, r3, r1
-    checkbuf15      r10, r11, r4, r2, r12
-    lsls            r8, r8, #0x1
-    bne             1b
-6:
-    add             r12, sp, #0x20   /* r12 = t1 */
-    ldr             r8, [sp, #0x14]  /* r8 = index1 */
-    adds            r12, #0xc0       /* r12 = t2 + (DCTSIZE2/2) */
-    cmp             r8, #0x0
-    beq             6f
-    clz             r2, r8
-    sub             r12, r12, lr
-    lsl             r8, r8, r2
-    add             r2, r2, r12, lsr #1
-    add             lr, lr, r2, lsl #1
-    b               7f
-1:
-    clz             r2, r8
-    add             lr, lr, r2, lsl #1
-    lsl             r8, r8, r2
-7:
-    ldrh            r1, [lr, #-126]
-2:
-    cmp             r2, #0x10
-    blt             3f
-    sub             r2, r2, #0x10
-    put_bits        r11, r4, r0, r6
-    cmp             r4, #0x10
-    blt             2b
-    eor             r3, r3, r3
-    emit_byte       r10, r11, r4, r3, r12
-    emit_byte       r10, r11, r4, r3, r12
-    b               2b
-3:
-    add             r2, r1, r2, lsl #4
-    ldrh            r3, [lr, #2]!
-    ldr             r12, [r9, r2, lsl #2]
-    ldrb            r2, [r5, r2]
-    put_bits        r11, r4, r12, r2
-    checkbuf15      r10, r11, r4, r2, r12
-    put_bits        r11, r4, r3, r1
-    checkbuf15      r10, r11, r4, r2, r12
-    lsls            r8, r8, #0x1
-    bne             1b
-6:
-    add             r0, sp, #0x20
-    add             r0, #0xfe
-    cmp             lr, r0
-    bhs             1f
-    ldr             r1, [r9]
-    ldrb            r0, [r5]
-    put_bits        r11, r4, r1, r0
-    checkbuf15      r10, r11, r4, r0, r1
-1:
-    ldr             r12, [sp, #0x18]
-    str             r11, [r12, #0x8]
-    str             r4, [r12, #0xc]
-    add             r0, r10, #0x1
-    add             r4, sp, #0x140
-    vld1.64         {d8, d9, d10, d11}, [r4, :128]!
-    vld1.64         {d12, d13, d14, d15}, [r4, :128]
-    sub             r4, r7, #0x1c
-    mov             sp, r4
-    pop             {r4, r5, r6, r7, r8, r9, r10, r11, pc}
-
-.purgem emit_byte
-.purgem put_bits
-.purgem checkbuf15
diff --git a/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h b/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h
new file mode 100644
index 0000000..73c57ae
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2020-2021, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#if defined(__clang__) || defined(_MSC_VER)
+#define HAVE_VLD1_S16_X3
+#define HAVE_VLD1_U16_X2
+#define HAVE_VLD1Q_U8_X4
+#endif
+
+/* Define compiler-independent count-leading-zeros and byte-swap macros */
+#if defined(_MSC_VER) && !defined(__clang__)
+#define BUILTIN_CLZ(x)  _CountLeadingZeros(x)
+#define BUILTIN_CLZLL(x)  _CountLeadingZeros64(x)
+#define BUILTIN_BSWAP64(x)  _byteswap_uint64(x)
+#elif defined(__clang__) || defined(__GNUC__)
+#define BUILTIN_CLZ(x)  __builtin_clz(x)
+#define BUILTIN_CLZLL(x)  __builtin_clzll(x)
+#define BUILTIN_BSWAP64(x)  __builtin_bswap64(x)
+#else
+#error "Unknown compiler"
+#endif
diff --git a/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h.in b/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h.in
new file mode 100644
index 0000000..d403f22
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/simd/arm/neon-compat.h.in
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020, D. R. Commander.  All Rights Reserved.
+ * Copyright (C) 2020-2021, Arm Limited.  All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#cmakedefine HAVE_VLD1_S16_X3
+#cmakedefine HAVE_VLD1_U16_X2
+#cmakedefine HAVE_VLD1Q_U8_X4
+
+/* Define compiler-independent count-leading-zeros and byte-swap macros */
+#if defined(_MSC_VER) && !defined(__clang__)
+#define BUILTIN_CLZ(x)  _CountLeadingZeros(x)
+#define BUILTIN_CLZLL(x)  _CountLeadingZeros64(x)
+#define BUILTIN_BSWAP64(x)  _byteswap_uint64(x)
+#elif defined(__clang__) || defined(__GNUC__)
+#define BUILTIN_CLZ(x)  __builtin_clz(x)
+#define BUILTIN_CLZLL(x)  __builtin_clzll(x)
+#define BUILTIN_BSWAP64(x)  __builtin_bswap64(x)
+#else
+#error "Unknown compiler"
+#endif
diff --git a/src/third_party/libjpeg-turbo/simd/arm64/jsimd_neon.S b/src/third_party/libjpeg-turbo/simd/arm64/jsimd_neon.S
deleted file mode 100644
index 218e1ae..0000000
--- a/src/third_party/libjpeg-turbo/simd/arm64/jsimd_neon.S
+++ /dev/null
@@ -1,3427 +0,0 @@
-/*
- * ARMv8 NEON optimizations for libjpeg-turbo
- *
- * Copyright (C) 2009-2011, Nokia Corporation and/or its subsidiary(-ies).
- *                          All Rights Reserved.
- * Author:  Siarhei Siamashka <siarhei.siamashka@nokia.com>
- * Copyright (C) 2013-2014, Linaro Limited.  All Rights Reserved.
- * Author:  Ragesh Radhakrishnan <ragesh.r@linaro.org>
- * Copyright (C) 2014-2016, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2015-2016, 2018, Matthieu Darbois.  All Rights Reserved.
- * Copyright (C) 2016, Siarhei Siamashka.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack, "", %progbits  /* mark stack as non-executable */
-#endif
-
-.text
-
-
-#define RESPECT_STRICT_ALIGNMENT  1
-
-
-/*****************************************************************************/
-
-/* Supplementary macro for setting function attributes */
-.macro asm_function fname
-#ifdef __APPLE__
-    .private_extern _\fname
-    .globl _\fname
-_\fname:
-#else
-    .global \fname
-#ifdef __ELF__
-    .hidden \fname
-    .type \fname, %function
-#endif
-\fname:
-#endif
-.endm
-
-/* Transpose elements of single 128 bit registers */
-.macro transpose_single x0, x1, xi, xilen, literal
-    ins             \xi\xilen[0], \x0\xilen[0]
-    ins             \x1\xilen[0], \x0\xilen[1]
-    trn1            \x0\literal, \x0\literal, \x1\literal
-    trn2            \x1\literal, \xi\literal, \x1\literal
-.endm
-
-/* Transpose elements of 2 differnet registers */
-.macro transpose x0, x1, xi, xilen, literal
-    mov             \xi\xilen, \x0\xilen
-    trn1            \x0\literal, \x0\literal, \x1\literal
-    trn2            \x1\literal, \xi\literal, \x1\literal
-.endm
-
-/* Transpose a block of 4x4 coefficients in four 64-bit registers */
-.macro transpose_4x4_32 x0, x0len, x1, x1len, x2, x2len, x3, x3len, xi, xilen
-    mov             \xi\xilen, \x0\xilen
-    trn1            \x0\x0len, \x0\x0len, \x2\x2len
-    trn2            \x2\x2len, \xi\x0len, \x2\x2len
-    mov             \xi\xilen, \x1\xilen
-    trn1            \x1\x1len, \x1\x1len, \x3\x3len
-    trn2            \x3\x3len, \xi\x1len, \x3\x3len
-.endm
-
-.macro transpose_4x4_16 x0, x0len, x1, x1len, x2, x2len, x3, x3len, xi, xilen
-    mov             \xi\xilen, \x0\xilen
-    trn1            \x0\x0len, \x0\x0len, \x1\x1len
-    trn2            \x1\x2len, \xi\x0len, \x1\x2len
-    mov             \xi\xilen, \x2\xilen
-    trn1            \x2\x2len, \x2\x2len, \x3\x3len
-    trn2            \x3\x2len, \xi\x1len, \x3\x3len
-.endm
-
-.macro transpose_4x4 x0, x1, x2, x3, x5
-    transpose_4x4_16 \x0, .4h, \x1, .4h, \x2, .4h, \x3, .4h, \x5, .16b
-    transpose_4x4_32 \x0, .2s, \x1, .2s, \x2, .2s, \x3, .2s, \x5, .16b
-.endm
-
-.macro transpose_8x8 l0, l1, l2, l3, l4, l5, l6, l7, t0, t1, t2, t3
-    trn1            \t0\().8h, \l0\().8h, \l1\().8h
-    trn1            \t1\().8h, \l2\().8h, \l3\().8h
-    trn1            \t2\().8h, \l4\().8h, \l5\().8h
-    trn1            \t3\().8h, \l6\().8h, \l7\().8h
-    trn2            \l1\().8h, \l0\().8h, \l1\().8h
-    trn2            \l3\().8h, \l2\().8h, \l3\().8h
-    trn2            \l5\().8h, \l4\().8h, \l5\().8h
-    trn2            \l7\().8h, \l6\().8h, \l7\().8h
-
-    trn1            \l4\().4s, \t2\().4s, \t3\().4s
-    trn2            \t3\().4s, \t2\().4s, \t3\().4s
-    trn1            \t2\().4s, \t0\().4s, \t1\().4s
-    trn2            \l2\().4s, \t0\().4s, \t1\().4s
-    trn1            \t0\().4s, \l1\().4s, \l3\().4s
-    trn2            \l3\().4s, \l1\().4s, \l3\().4s
-    trn2            \t1\().4s, \l5\().4s, \l7\().4s
-    trn1            \l5\().4s, \l5\().4s, \l7\().4s
-
-    trn2            \l6\().2d, \l2\().2d, \t3\().2d
-    trn1            \l0\().2d, \t2\().2d, \l4\().2d
-    trn1            \l1\().2d, \t0\().2d, \l5\().2d
-    trn2            \l7\().2d, \l3\().2d, \t1\().2d
-    trn1            \l2\().2d, \l2\().2d, \t3\().2d
-    trn2            \l4\().2d, \t2\().2d, \l4\().2d
-    trn1            \l3\().2d, \l3\().2d, \t1\().2d
-    trn2            \l5\().2d, \t0\().2d, \l5\().2d
-.endm
-
-
-#define CENTERJSAMPLE  128
-
-/*****************************************************************************/
-
-/*
- * Perform dequantization and inverse DCT on one block of coefficients.
- *
- * GLOBAL(void)
- * jsimd_idct_islow_neon(void *dct_table, JCOEFPTR coef_block,
- *                       JSAMPARRAY output_buf, JDIMENSION output_col)
- */
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-
-#define F_0_298   2446  /* FIX(0.298631336) */
-#define F_0_390   3196  /* FIX(0.390180644) */
-#define F_0_541   4433  /* FIX(0.541196100) */
-#define F_0_765   6270  /* FIX(0.765366865) */
-#define F_0_899   7373  /* FIX(0.899976223) */
-#define F_1_175   9633  /* FIX(1.175875602) */
-#define F_1_501  12299  /* FIX(1.501321110) */
-#define F_1_847  15137  /* FIX(1.847759065) */
-#define F_1_961  16069  /* FIX(1.961570560) */
-#define F_2_053  16819  /* FIX(2.053119869) */
-#define F_2_562  20995  /* FIX(2.562915447) */
-#define F_3_072  25172  /* FIX(3.072711026) */
-
-.balign 16
-Ljsimd_idct_islow_neon_consts:
-  .short F_0_298
-  .short -F_0_390
-  .short F_0_541
-  .short F_0_765
-  .short - F_0_899
-  .short F_1_175
-  .short F_1_501
-  .short - F_1_847
-  .short - F_1_961
-  .short F_2_053
-  .short - F_2_562
-  .short F_3_072
-  .short 0          /* padding */
-  .short 0
-  .short 0
-  .short 0
-
-#undef F_0_298
-#undef F_0_390
-#undef F_0_541
-#undef F_0_765
-#undef F_0_899
-#undef F_1_175
-#undef F_1_501
-#undef F_1_847
-#undef F_1_961
-#undef F_2_053
-#undef F_2_562
-#undef F_3_072
-
-#define XFIX_P_0_298  v0.h[0]
-#define XFIX_N_0_390  v0.h[1]
-#define XFIX_P_0_541  v0.h[2]
-#define XFIX_P_0_765  v0.h[3]
-#define XFIX_N_0_899  v0.h[4]
-#define XFIX_P_1_175  v0.h[5]
-#define XFIX_P_1_501  v0.h[6]
-#define XFIX_N_1_847  v0.h[7]
-#define XFIX_N_1_961  v1.h[0]
-#define XFIX_P_2_053  v1.h[1]
-#define XFIX_N_2_562  v1.h[2]
-#define XFIX_P_3_072  v1.h[3]
-
-asm_function jsimd_idct_islow_neon
-    DCT_TABLE       .req x0
-    COEF_BLOCK      .req x1
-    OUTPUT_BUF      .req x2
-    OUTPUT_COL      .req x3
-    TMP1            .req x0
-    TMP2            .req x1
-    TMP3            .req x9
-    TMP4            .req x10
-    TMP5            .req x11
-    TMP6            .req x12
-    TMP7            .req x13
-    TMP8            .req x14
-
-    /* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
-       guarantee that the upper (unused) 32 bits of x3 are valid.  This
-       instruction ensures that those bits are set to zero. */
-    uxtw x3, w3
-
-    sub             sp, sp, #64
-    adr             x15, Ljsimd_idct_islow_neon_consts
-    mov             x10, sp
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x10], #32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x10], #32
-    ld1             {v0.8h, v1.8h}, [x15]
-    ld1             {v2.8h, v3.8h, v4.8h, v5.8h}, [COEF_BLOCK], #64
-    ld1             {v18.8h, v19.8h, v20.8h, v21.8h}, [DCT_TABLE], #64
-    ld1             {v6.8h, v7.8h, v8.8h, v9.8h}, [COEF_BLOCK], #64
-    ld1             {v22.8h, v23.8h, v24.8h, v25.8h}, [DCT_TABLE], #64
-
-    cmeq            v16.8h, v3.8h, #0
-    cmeq            v26.8h, v4.8h, #0
-    cmeq            v27.8h, v5.8h, #0
-    cmeq            v28.8h, v6.8h, #0
-    cmeq            v29.8h, v7.8h, #0
-    cmeq            v30.8h, v8.8h, #0
-    cmeq            v31.8h, v9.8h, #0
-
-    and             v10.16b, v16.16b, v26.16b
-    and             v11.16b, v27.16b, v28.16b
-    and             v12.16b, v29.16b, v30.16b
-    and             v13.16b, v31.16b, v10.16b
-    and             v14.16b, v11.16b, v12.16b
-    mul             v2.8h, v2.8h, v18.8h
-    and             v15.16b, v13.16b, v14.16b
-    shl             v10.8h, v2.8h, #(PASS1_BITS)
-    sqxtn           v16.8b, v15.8h
-    mov             TMP1, v16.d[0]
-    mvn             TMP2, TMP1
-
-    cbnz            TMP2, 2f
-    /* case all AC coeffs are zeros */
-    dup             v2.2d, v10.d[0]
-    dup             v6.2d, v10.d[1]
-    mov             v3.16b, v2.16b
-    mov             v7.16b, v6.16b
-    mov             v4.16b, v2.16b
-    mov             v8.16b, v6.16b
-    mov             v5.16b, v2.16b
-    mov             v9.16b, v6.16b
-1:
-    /* for this transpose, we should organise data like this:
-     * 00, 01, 02, 03, 40, 41, 42, 43
-     * 10, 11, 12, 13, 50, 51, 52, 53
-     * 20, 21, 22, 23, 60, 61, 62, 63
-     * 30, 31, 32, 33, 70, 71, 72, 73
-     * 04, 05, 06, 07, 44, 45, 46, 47
-     * 14, 15, 16, 17, 54, 55, 56, 57
-     * 24, 25, 26, 27, 64, 65, 66, 67
-     * 34, 35, 36, 37, 74, 75, 76, 77
-     */
-    trn1            v28.8h, v2.8h, v3.8h
-    trn1            v29.8h, v4.8h, v5.8h
-    trn1            v30.8h, v6.8h, v7.8h
-    trn1            v31.8h, v8.8h, v9.8h
-    trn2            v16.8h, v2.8h, v3.8h
-    trn2            v17.8h, v4.8h, v5.8h
-    trn2            v18.8h, v6.8h, v7.8h
-    trn2            v19.8h, v8.8h, v9.8h
-    trn1            v2.4s, v28.4s, v29.4s
-    trn1            v6.4s, v30.4s, v31.4s
-    trn1            v3.4s, v16.4s, v17.4s
-    trn1            v7.4s, v18.4s, v19.4s
-    trn2            v4.4s, v28.4s, v29.4s
-    trn2            v8.4s, v30.4s, v31.4s
-    trn2            v5.4s, v16.4s, v17.4s
-    trn2            v9.4s, v18.4s, v19.4s
-    /* Even part: reverse the even part of the forward DCT. */
-    add             v18.8h, v4.8h, v8.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]) + DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]) */
-    add             v22.8h, v2.8h, v6.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) + DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull2          v19.4s, v18.8h, XFIX_P_0_541   /* z1h z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sub             v26.8h, v2.8h, v6.8h           /* z2 - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) - DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull           v18.4s, v18.4h, XFIX_P_0_541   /* z1l z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sshll2          v23.4s, v22.8h, #(CONST_BITS)  /* tmp0h tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    mov             v21.16b, v19.16b               /* tmp3 = z1 */
-    mov             v20.16b, v18.16b               /* tmp3 = z1 */
-    smlal2          v19.4s, v8.8h, XFIX_N_1_847    /* tmp2h tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    smlal           v18.4s, v8.4h, XFIX_N_1_847    /* tmp2l tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    sshll2          v27.4s, v26.8h, #(CONST_BITS)  /* tmp1h tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    smlal2          v21.4s, v4.8h, XFIX_P_0_765    /* tmp3h tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    smlal           v20.4s, v4.4h, XFIX_P_0_765    /* tmp3l tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    sshll           v22.4s, v22.4h, #(CONST_BITS)  /* tmp0l tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    sshll           v26.4s, v26.4h, #(CONST_BITS)  /* tmp1l tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    add             v2.4s, v22.4s, v20.4s          /* tmp10l tmp10 = tmp0 + tmp3; */
-    sub             v6.4s, v22.4s, v20.4s          /* tmp13l tmp13 = tmp0 - tmp3; */
-    add             v8.4s, v26.4s, v18.4s          /* tmp11l tmp11 = tmp1 + tmp2; */
-    sub             v4.4s, v26.4s, v18.4s          /* tmp12l tmp12 = tmp1 - tmp2; */
-    add             v28.4s, v23.4s, v21.4s         /* tmp10h tmp10 = tmp0 + tmp3; */
-    sub             v31.4s, v23.4s, v21.4s         /* tmp13h tmp13 = tmp0 - tmp3; */
-    add             v29.4s, v27.4s, v19.4s         /* tmp11h tmp11 = tmp1 + tmp2; */
-    sub             v30.4s, v27.4s, v19.4s         /* tmp12h tmp12 = tmp1 - tmp2; */
-
-    /* Odd part per figure 8; the matrix is unitary and hence its
-     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
-     */
-
-    add             v22.8h, v9.8h, v5.8h    /* z3 = tmp0 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v24.8h, v7.8h, v3.8h    /* z4 = tmp1 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v18.8h, v9.8h, v3.8h    /* z1 = tmp0 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v20.8h, v7.8h, v5.8h    /* z2 = tmp1 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v26.8h, v22.8h, v24.8h  /* z5 = z3 + z4 */
-
-    smull2          v11.4s, v9.8h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull2          v13.4s, v7.8h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull2          v15.4s, v5.8h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull2          v17.4s, v3.8h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull2          v27.4s, v26.8h, XFIX_P_1_175  /* z5h z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull2          v23.4s, v22.8h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull2          v25.4s, v24.8h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull2          v19.4s, v18.8h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull2          v21.4s, v20.8h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    smull           v10.4s, v9.4h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull           v12.4s, v7.4h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull           v14.4s, v5.4h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull           v16.4s, v3.4h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull           v26.4s, v26.4h, XFIX_P_1_175  /* z5l z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull           v22.4s, v22.4h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull           v24.4s, v24.4h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull           v18.4s, v18.4h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull           v20.4s, v20.4h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    add             v23.4s, v23.4s, v27.4s  /* z3 += z5 */
-    add             v22.4s, v22.4s, v26.4s  /* z3 += z5 */
-    add             v25.4s, v25.4s, v27.4s  /* z4 += z5 */
-    add             v24.4s, v24.4s, v26.4s  /* z4 += z5 */
-
-    add             v11.4s, v11.4s, v19.4s  /* tmp0 += z1 */
-    add             v10.4s, v10.4s, v18.4s  /* tmp0 += z1 */
-    add             v13.4s, v13.4s, v21.4s  /* tmp1 += z2 */
-    add             v12.4s, v12.4s, v20.4s  /* tmp1 += z2 */
-    add             v15.4s, v15.4s, v21.4s  /* tmp2 += z2 */
-    add             v14.4s, v14.4s, v20.4s  /* tmp2 += z2 */
-    add             v17.4s, v17.4s, v19.4s  /* tmp3 += z1 */
-    add             v16.4s, v16.4s, v18.4s  /* tmp3 += z1 */
-
-    add             v11.4s, v11.4s, v23.4s  /* tmp0 += z3 */
-    add             v10.4s, v10.4s, v22.4s  /* tmp0 += z3 */
-    add             v13.4s, v13.4s, v25.4s  /* tmp1 += z4 */
-    add             v12.4s, v12.4s, v24.4s  /* tmp1 += z4 */
-    add             v17.4s, v17.4s, v25.4s  /* tmp3 += z4 */
-    add             v16.4s, v16.4s, v24.4s  /* tmp3 += z4 */
-    add             v15.4s, v15.4s, v23.4s  /* tmp2 += z3 */
-    add             v14.4s, v14.4s, v22.4s  /* tmp2 += z3 */
-
-    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
-    add             v18.4s, v2.4s, v16.4s   /* tmp10 + tmp3 */
-    add             v19.4s, v28.4s, v17.4s  /* tmp10 + tmp3 */
-    sub             v20.4s, v2.4s, v16.4s   /* tmp10 - tmp3 */
-    sub             v21.4s, v28.4s, v17.4s  /* tmp10 - tmp3 */
-    add             v22.4s, v8.4s, v14.4s   /* tmp11 + tmp2 */
-    add             v23.4s, v29.4s, v15.4s  /* tmp11 + tmp2 */
-    sub             v24.4s, v8.4s, v14.4s   /* tmp11 - tmp2 */
-    sub             v25.4s, v29.4s, v15.4s  /* tmp11 - tmp2 */
-    add             v26.4s, v4.4s, v12.4s   /* tmp12 + tmp1 */
-    add             v27.4s, v30.4s, v13.4s  /* tmp12 + tmp1 */
-    sub             v28.4s, v4.4s, v12.4s   /* tmp12 - tmp1 */
-    sub             v29.4s, v30.4s, v13.4s  /* tmp12 - tmp1 */
-    add             v14.4s, v6.4s, v10.4s   /* tmp13 + tmp0 */
-    add             v15.4s, v31.4s, v11.4s  /* tmp13 + tmp0 */
-    sub             v16.4s, v6.4s, v10.4s   /* tmp13 - tmp0 */
-    sub             v17.4s, v31.4s, v11.4s  /* tmp13 - tmp0 */
-
-    shrn            v2.4h, v18.4s, #16  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3) */
-    shrn            v9.4h, v20.4s, #16  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3) */
-    shrn            v3.4h, v22.4s, #16  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3) */
-    shrn            v8.4h, v24.4s, #16  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3) */
-    shrn            v4.4h, v26.4s, #16  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3) */
-    shrn            v7.4h, v28.4s, #16  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3) */
-    shrn            v5.4h, v14.4s, #16  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3) */
-    shrn            v6.4h, v16.4s, #16  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v2.8h, v19.4s, #16  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v9.8h, v21.4s, #16  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v3.8h, v23.4s, #16  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v8.8h, v25.4s, #16  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v4.8h, v27.4s, #16  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v7.8h, v29.4s, #16  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v5.8h, v15.4s, #16  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3) */
-    shrn2           v6.8h, v17.4s, #16  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3) */
-    movi            v0.16b, #(CENTERJSAMPLE)
-    /* Prepare pointers (dual-issue with NEON instructions) */
-      ldp             TMP1, TMP2, [OUTPUT_BUF], 16
-    sqrshrn         v28.8b, v2.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      ldp             TMP3, TMP4, [OUTPUT_BUF], 16
-    sqrshrn         v29.8b, v3.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      add             TMP1, TMP1, OUTPUT_COL
-    sqrshrn         v30.8b, v4.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      add             TMP2, TMP2, OUTPUT_COL
-    sqrshrn         v31.8b, v5.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      add             TMP3, TMP3, OUTPUT_COL
-    sqrshrn2        v28.16b, v6.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      add             TMP4, TMP4, OUTPUT_COL
-    sqrshrn2        v29.16b, v7.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      ldp             TMP5, TMP6, [OUTPUT_BUF], 16
-    sqrshrn2        v30.16b, v8.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      ldp             TMP7, TMP8, [OUTPUT_BUF], 16
-    sqrshrn2        v31.16b, v9.8h, #(CONST_BITS+PASS1_BITS+3-16)
-      add             TMP5, TMP5, OUTPUT_COL
-    add             v16.16b, v28.16b, v0.16b
-      add             TMP6, TMP6, OUTPUT_COL
-    add             v18.16b, v29.16b, v0.16b
-      add             TMP7, TMP7, OUTPUT_COL
-    add             v20.16b, v30.16b, v0.16b
-      add             TMP8, TMP8, OUTPUT_COL
-    add             v22.16b, v31.16b, v0.16b
-
-    /* Transpose the final 8-bit samples */
-    trn1            v28.16b, v16.16b, v18.16b
-    trn1            v30.16b, v20.16b, v22.16b
-    trn2            v29.16b, v16.16b, v18.16b
-    trn2            v31.16b, v20.16b, v22.16b
-
-    trn1            v16.8h, v28.8h, v30.8h
-    trn2            v18.8h, v28.8h, v30.8h
-    trn1            v20.8h, v29.8h, v31.8h
-    trn2            v22.8h, v29.8h, v31.8h
-
-    uzp1            v28.4s, v16.4s, v18.4s
-    uzp2            v30.4s, v16.4s, v18.4s
-    uzp1            v29.4s, v20.4s, v22.4s
-    uzp2            v31.4s, v20.4s, v22.4s
-
-    /* Store results to the output buffer */
-    st1             {v28.d}[0], [TMP1]
-    st1             {v29.d}[0], [TMP2]
-    st1             {v28.d}[1], [TMP3]
-    st1             {v29.d}[1], [TMP4]
-    st1             {v30.d}[0], [TMP5]
-    st1             {v31.d}[0], [TMP6]
-    st1             {v30.d}[1], [TMP7]
-    st1             {v31.d}[1], [TMP8]
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], #32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], #32
-    blr             x30
-
-.balign 16
-2:
-    mul             v3.8h, v3.8h, v19.8h
-    mul             v4.8h, v4.8h, v20.8h
-    mul             v5.8h, v5.8h, v21.8h
-    add             TMP4, xzr, TMP2, LSL #32
-    mul             v6.8h, v6.8h, v22.8h
-    mul             v7.8h, v7.8h, v23.8h
-    adds            TMP3, xzr, TMP2, LSR #32
-    mul             v8.8h, v8.8h, v24.8h
-    mul             v9.8h, v9.8h, v25.8h
-    b.ne            3f
-    /* Right AC coef is zero */
-    dup             v15.2d, v10.d[1]
-    /* Even part: reverse the even part of the forward DCT. */
-    add             v18.4h, v4.4h, v8.4h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]) + DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]) */
-    add             v22.4h, v2.4h, v6.4h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) + DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    sub             v26.4h, v2.4h, v6.4h           /* z2 - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) - DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull           v18.4s, v18.4h, XFIX_P_0_541   /* z1l z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sshll           v22.4s, v22.4h, #(CONST_BITS)  /* tmp0l tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    mov             v20.16b, v18.16b               /* tmp3 = z1 */
-    sshll           v26.4s, v26.4h, #(CONST_BITS)  /* tmp1l tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    smlal           v18.4s, v8.4h, XFIX_N_1_847    /* tmp2l tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    smlal           v20.4s, v4.4h, XFIX_P_0_765    /* tmp3l tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    add             v2.4s, v22.4s, v20.4s          /* tmp10l tmp10 = tmp0 + tmp3; */
-    sub             v6.4s, v22.4s, v20.4s          /* tmp13l tmp13 = tmp0 - tmp3; */
-    add             v8.4s, v26.4s, v18.4s          /* tmp11l tmp11 = tmp1 + tmp2; */
-    sub             v4.4s, v26.4s, v18.4s          /* tmp12l tmp12 = tmp1 - tmp2; */
-
-    /* Odd part per figure 8; the matrix is unitary and hence its
-     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
-     */
-
-    add             v22.4h, v9.4h, v5.4h    /* z3 = tmp0 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v24.4h, v7.4h, v3.4h    /* z4 = tmp1 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v18.4h, v9.4h, v3.4h    /* z1 = tmp0 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v20.4h, v7.4h, v5.4h    /* z2 = tmp1 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v26.4h, v22.4h, v24.4h  /* z5 = z3 + z4 */
-
-    smull           v10.4s, v9.4h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull           v12.4s, v7.4h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull           v14.4s, v5.4h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull           v16.4s, v3.4h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull           v26.4s, v26.4h, XFIX_P_1_175  /* z5l z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull           v22.4s, v22.4h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull           v24.4s, v24.4h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull           v18.4s, v18.4h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull           v20.4s, v20.4h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    add             v22.4s, v22.4s, v26.4s  /* z3 += z5 */
-    add             v24.4s, v24.4s, v26.4s  /* z4 += z5 */
-
-    add             v10.4s, v10.4s, v18.4s  /* tmp0 += z1 */
-    add             v12.4s, v12.4s, v20.4s  /* tmp1 += z2 */
-    add             v14.4s, v14.4s, v20.4s  /* tmp2 += z2 */
-    add             v16.4s, v16.4s, v18.4s  /* tmp3 += z1 */
-
-    add             v10.4s, v10.4s, v22.4s  /* tmp0 += z3 */
-    add             v12.4s, v12.4s, v24.4s  /* tmp1 += z4 */
-    add             v16.4s, v16.4s, v24.4s  /* tmp3 += z4 */
-    add             v14.4s, v14.4s, v22.4s  /* tmp2 += z3 */
-
-    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
-    add             v18.4s, v2.4s, v16.4s  /* tmp10 + tmp3 */
-    sub             v20.4s, v2.4s, v16.4s  /* tmp10 - tmp3 */
-    add             v22.4s, v8.4s, v14.4s  /* tmp11 + tmp2 */
-    sub             v24.4s, v8.4s, v14.4s  /* tmp11 - tmp2 */
-    add             v26.4s, v4.4s, v12.4s  /* tmp12 + tmp1 */
-    sub             v28.4s, v4.4s, v12.4s  /* tmp12 - tmp1 */
-    add             v14.4s, v6.4s, v10.4s  /* tmp13 + tmp0 */
-    sub             v16.4s, v6.4s, v10.4s  /* tmp13 - tmp0 */
-
-    rshrn           v2.4h, v18.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS) */
-    rshrn           v3.4h, v22.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn           v4.4h, v26.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn           v5.4h, v14.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v2.8h, v16.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v3.8h, v28.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn2          v4.8h, v24.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn2          v5.8h, v20.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS) */
-    mov             v6.16b, v15.16b
-    mov             v7.16b, v15.16b
-    mov             v8.16b, v15.16b
-    mov             v9.16b, v15.16b
-    b               1b
-
-.balign 16
-3:
-    cbnz            TMP4, 4f
-    /* Left AC coef is zero */
-    dup             v14.2d, v10.d[0]
-    /* Even part: reverse the even part of the forward DCT. */
-    add             v18.8h, v4.8h, v8.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]) + DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]) */
-    add             v22.8h, v2.8h, v6.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) + DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull2          v19.4s, v18.8h, XFIX_P_0_541   /* z1h z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sub             v26.8h, v2.8h, v6.8h           /* z2 - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) - DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    sshll2          v23.4s, v22.8h, #(CONST_BITS)  /* tmp0h tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    mov             v21.16b, v19.16b               /* tmp3 = z1 */
-    smlal2          v19.4s, v8.8h, XFIX_N_1_847    /* tmp2h tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    sshll2          v27.4s, v26.8h, #(CONST_BITS)  /* tmp1h tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    smlal2          v21.4s, v4.8h, XFIX_P_0_765    /* tmp3h tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    add             v28.4s, v23.4s, v21.4s         /* tmp10h tmp10 = tmp0 + tmp3; */
-    sub             v31.4s, v23.4s, v21.4s         /* tmp13h tmp13 = tmp0 - tmp3; */
-    add             v29.4s, v27.4s, v19.4s         /* tmp11h tmp11 = tmp1 + tmp2; */
-    sub             v30.4s, v27.4s, v19.4s         /* tmp12h tmp12 = tmp1 - tmp2; */
-
-    /* Odd part per figure 8; the matrix is unitary and hence its
-     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
-     */
-
-    add             v22.8h, v9.8h, v5.8h    /* z3 = tmp0 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v24.8h, v7.8h, v3.8h    /* z4 = tmp1 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v18.8h, v9.8h, v3.8h    /* z1 = tmp0 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v20.8h, v7.8h, v5.8h    /* z2 = tmp1 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v26.8h, v22.8h, v24.8h  /* z5 = z3 + z4 */
-
-    smull2          v11.4s, v9.8h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull2          v13.4s, v7.8h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull2          v15.4s, v5.8h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull2          v17.4s, v3.8h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull2          v27.4s, v26.8h, XFIX_P_1_175  /* z5h z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull2          v23.4s, v22.8h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull2          v25.4s, v24.8h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull2          v19.4s, v18.8h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull2          v21.4s, v20.8h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    add             v23.4s, v23.4s, v27.4s  /* z3 += z5 */
-    add             v22.4s, v22.4s, v26.4s  /* z3 += z5 */
-    add             v25.4s, v25.4s, v27.4s  /* z4 += z5 */
-    add             v24.4s, v24.4s, v26.4s  /* z4 += z5 */
-
-    add             v11.4s, v11.4s, v19.4s  /* tmp0 += z1 */
-    add             v13.4s, v13.4s, v21.4s  /* tmp1 += z2 */
-    add             v15.4s, v15.4s, v21.4s  /* tmp2 += z2 */
-    add             v17.4s, v17.4s, v19.4s  /* tmp3 += z1 */
-
-    add             v11.4s, v11.4s, v23.4s  /* tmp0 += z3 */
-    add             v13.4s, v13.4s, v25.4s  /* tmp1 += z4 */
-    add             v17.4s, v17.4s, v25.4s  /* tmp3 += z4 */
-    add             v15.4s, v15.4s, v23.4s  /* tmp2 += z3 */
-
-    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
-    add             v19.4s, v28.4s, v17.4s  /* tmp10 + tmp3 */
-    sub             v21.4s, v28.4s, v17.4s  /* tmp10 - tmp3 */
-    add             v23.4s, v29.4s, v15.4s  /* tmp11 + tmp2 */
-    sub             v25.4s, v29.4s, v15.4s  /* tmp11 - tmp2 */
-    add             v27.4s, v30.4s, v13.4s  /* tmp12 + tmp1 */
-    sub             v29.4s, v30.4s, v13.4s  /* tmp12 - tmp1 */
-    add             v15.4s, v31.4s, v11.4s  /* tmp13 + tmp0 */
-    sub             v17.4s, v31.4s, v11.4s  /* tmp13 - tmp0 */
-
-    mov             v2.16b, v14.16b
-    mov             v3.16b, v14.16b
-    mov             v4.16b, v14.16b
-    mov             v5.16b, v14.16b
-    rshrn           v6.4h, v19.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS) */
-    rshrn           v7.4h, v23.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn           v8.4h, v27.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn           v9.4h, v15.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v6.8h, v17.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v7.8h, v29.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn2          v8.8h, v25.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn2          v9.8h, v21.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS) */
-    b               1b
-
-.balign 16
-4:
-    /* "No" AC coef is zero */
-    /* Even part: reverse the even part of the forward DCT. */
-    add             v18.8h, v4.8h, v8.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]) + DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]) */
-    add             v22.8h, v2.8h, v6.8h           /* z2 + z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) + DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull2          v19.4s, v18.8h, XFIX_P_0_541   /* z1h z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sub             v26.8h, v2.8h, v6.8h           /* z2 - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) - DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]) */
-    smull           v18.4s, v18.4h, XFIX_P_0_541   /* z1l z1 = MULTIPLY(z2 + z3, FIX_0_541196100); */
-    sshll2          v23.4s, v22.8h, #(CONST_BITS)  /* tmp0h tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    mov             v21.16b, v19.16b               /* tmp3 = z1 */
-    mov             v20.16b, v18.16b               /* tmp3 = z1 */
-    smlal2          v19.4s, v8.8h, XFIX_N_1_847    /* tmp2h tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    smlal           v18.4s, v8.4h, XFIX_N_1_847    /* tmp2l tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); */
-    sshll2          v27.4s, v26.8h, #(CONST_BITS)  /* tmp1h tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    smlal2          v21.4s, v4.8h, XFIX_P_0_765    /* tmp3h tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    smlal           v20.4s, v4.4h, XFIX_P_0_765    /* tmp3l tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); */
-    sshll           v22.4s, v22.4h, #(CONST_BITS)  /* tmp0l tmp0 = LEFT_SHIFT(z2 + z3, CONST_BITS); */
-    sshll           v26.4s, v26.4h, #(CONST_BITS)  /* tmp1l tmp1 = LEFT_SHIFT(z2 - z3, CONST_BITS); */
-    add             v2.4s, v22.4s, v20.4s          /* tmp10l tmp10 = tmp0 + tmp3; */
-    sub             v6.4s, v22.4s, v20.4s          /* tmp13l tmp13 = tmp0 - tmp3; */
-    add             v8.4s, v26.4s, v18.4s          /* tmp11l tmp11 = tmp1 + tmp2; */
-    sub             v4.4s, v26.4s, v18.4s          /* tmp12l tmp12 = tmp1 - tmp2; */
-    add             v28.4s, v23.4s, v21.4s         /* tmp10h tmp10 = tmp0 + tmp3; */
-    sub             v31.4s, v23.4s, v21.4s         /* tmp13h tmp13 = tmp0 - tmp3; */
-    add             v29.4s, v27.4s, v19.4s         /* tmp11h tmp11 = tmp1 + tmp2; */
-    sub             v30.4s, v27.4s, v19.4s         /* tmp12h tmp12 = tmp1 - tmp2; */
-
-    /* Odd part per figure 8; the matrix is unitary and hence its
-     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
-     */
-
-    add             v22.8h, v9.8h, v5.8h    /* z3 = tmp0 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v24.8h, v7.8h, v3.8h    /* z4 = tmp1 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v18.8h, v9.8h, v3.8h    /* z1 = tmp0 + tmp3 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]) + DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]) */
-    add             v20.8h, v7.8h, v5.8h    /* z2 = tmp1 + tmp2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]) + DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]) */
-    add             v26.8h, v22.8h, v24.8h  /* z5 = z3 + z4 */
-
-    smull2          v11.4s, v9.8h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull2          v13.4s, v7.8h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull2          v15.4s, v5.8h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull2          v17.4s, v3.8h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull2          v27.4s, v26.8h, XFIX_P_1_175  /* z5h z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull2          v23.4s, v22.8h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull2          v25.4s, v24.8h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull2          v19.4s, v18.8h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull2          v21.4s, v20.8h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    smull           v10.4s, v9.4h, XFIX_P_0_298   /* tmp0 = MULTIPLY(tmp0, FIX_0_298631336) */
-    smull           v12.4s, v7.4h, XFIX_P_2_053   /* tmp1 = MULTIPLY(tmp1, FIX_2_053119869) */
-    smull           v14.4s, v5.4h, XFIX_P_3_072   /* tmp2 = MULTIPLY(tmp2, FIX_3_072711026) */
-    smull           v16.4s, v3.4h, XFIX_P_1_501   /* tmp3 = MULTIPLY(tmp3, FIX_1_501321110) */
-    smull           v26.4s, v26.4h, XFIX_P_1_175  /* z5l z5 = MULTIPLY(z3 + z4, FIX_1_175875602) */
-    smull           v22.4s, v22.4h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560) */
-    smull           v24.4s, v24.4h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644) */
-    smull           v18.4s, v18.4h, XFIX_N_0_899  /* z1 = MULTIPLY(z1, -FIX_0_899976223) */
-    smull           v20.4s, v20.4h, XFIX_N_2_562  /* z2 = MULTIPLY(z2, -FIX_2_562915447) */
-
-    add             v23.4s, v23.4s, v27.4s  /* z3 += z5 */
-    add             v22.4s, v22.4s, v26.4s  /* z3 += z5 */
-    add             v25.4s, v25.4s, v27.4s  /* z4 += z5 */
-    add             v24.4s, v24.4s, v26.4s  /* z4 += z5 */
-
-    add             v11.4s, v11.4s, v19.4s  /* tmp0 += z1 */
-    add             v10.4s, v10.4s, v18.4s  /* tmp0 += z1 */
-    add             v13.4s, v13.4s, v21.4s  /* tmp1 += z2 */
-    add             v12.4s, v12.4s, v20.4s  /* tmp1 += z2 */
-    add             v15.4s, v15.4s, v21.4s  /* tmp2 += z2 */
-    add             v14.4s, v14.4s, v20.4s  /* tmp2 += z2 */
-    add             v17.4s, v17.4s, v19.4s  /* tmp3 += z1 */
-    add             v16.4s, v16.4s, v18.4s  /* tmp3 += z1 */
-
-    add             v11.4s, v11.4s, v23.4s  /* tmp0 += z3 */
-    add             v10.4s, v10.4s, v22.4s  /* tmp0 += z3 */
-    add             v13.4s, v13.4s, v25.4s  /* tmp1 += z4 */
-    add             v12.4s, v12.4s, v24.4s  /* tmp1 += z4 */
-    add             v17.4s, v17.4s, v25.4s  /* tmp3 += z4 */
-    add             v16.4s, v16.4s, v24.4s  /* tmp3 += z4 */
-    add             v15.4s, v15.4s, v23.4s  /* tmp2 += z3 */
-    add             v14.4s, v14.4s, v22.4s  /* tmp2 += z3 */
-
-    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
-
-    add             v18.4s, v2.4s, v16.4s   /* tmp10 + tmp3 */
-    add             v19.4s, v28.4s, v17.4s  /* tmp10 + tmp3 */
-    sub             v20.4s, v2.4s, v16.4s   /* tmp10 - tmp3 */
-    sub             v21.4s, v28.4s, v17.4s  /* tmp10 - tmp3 */
-    add             v22.4s, v8.4s, v14.4s   /* tmp11 + tmp2 */
-    add             v23.4s, v29.4s, v15.4s  /* tmp11 + tmp2 */
-    sub             v24.4s, v8.4s, v14.4s   /* tmp11 - tmp2 */
-    sub             v25.4s, v29.4s, v15.4s  /* tmp11 - tmp2 */
-    add             v26.4s, v4.4s, v12.4s   /* tmp12 + tmp1 */
-    add             v27.4s, v30.4s, v13.4s  /* tmp12 + tmp1 */
-    sub             v28.4s, v4.4s, v12.4s   /* tmp12 - tmp1 */
-    sub             v29.4s, v30.4s, v13.4s  /* tmp12 - tmp1 */
-    add             v14.4s, v6.4s, v10.4s   /* tmp13 + tmp0 */
-    add             v15.4s, v31.4s, v11.4s  /* tmp13 + tmp0 */
-    sub             v16.4s, v6.4s, v10.4s   /* tmp13 - tmp0 */
-    sub             v17.4s, v31.4s, v11.4s  /* tmp13 - tmp0 */
-
-    rshrn           v2.4h, v18.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS) */
-    rshrn           v3.4h, v22.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn           v4.4h, v26.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn           v5.4h, v14.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn           v6.4h, v19.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*0] = (int)DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS) */
-    rshrn           v7.4h, v23.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*1] = (int)DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn           v8.4h, v27.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*2] = (int)DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn           v9.4h, v15.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*3] = (int)DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v2.8h, v16.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v3.8h, v28.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn2          v4.8h, v24.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn2          v5.8h, v20.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS) */
-    rshrn2          v6.8h, v17.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*4] = (int)DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS) */
-    rshrn2          v7.8h, v29.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*5] = (int)DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS) */
-    rshrn2          v8.8h, v25.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*6] = (int)DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS) */
-    rshrn2          v9.8h, v21.4s, #(CONST_BITS-PASS1_BITS)  /* wsptr[DCTSIZE*7] = (int)DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS) */
-    b               1b
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-    .unreq          TMP5
-    .unreq          TMP6
-    .unreq          TMP7
-    .unreq          TMP8
-
-#undef CENTERJSAMPLE
-#undef CONST_BITS
-#undef PASS1_BITS
-#undef XFIX_P_0_298
-#undef XFIX_N_0_390
-#undef XFIX_P_0_541
-#undef XFIX_P_0_765
-#undef XFIX_N_0_899
-#undef XFIX_P_1_175
-#undef XFIX_P_1_501
-#undef XFIX_N_1_847
-#undef XFIX_N_1_961
-#undef XFIX_P_2_053
-#undef XFIX_N_2_562
-#undef XFIX_P_3_072
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_ifast_neon
- *
- * This function contains a fast, not so accurate integer implementation of
- * the inverse DCT (Discrete Cosine Transform). It uses the same calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_ifast'
- * function from jidctfst.c
- *
- * Normally 1-D AAN DCT needs 5 multiplications and 29 additions.
- * But in ARM NEON case some extra additions are required because VQDMULH
- * instruction can't handle the constants larger than 1. So the expressions
- * like "x * 1.082392200" have to be converted to "x * 0.082392200 + x",
- * which introduces an extra addition. Overall, there are 6 extra additions
- * per 1-D IDCT pass, totalling to 5 VQDMULH and 35 VADD/VSUB instructions.
- */
-
-#define XFIX_1_082392200  v0.h[0]
-#define XFIX_1_414213562  v0.h[1]
-#define XFIX_1_847759065  v0.h[2]
-#define XFIX_2_613125930  v0.h[3]
-
-.balign 16
-Ljsimd_idct_ifast_neon_consts:
-  .short (277 * 128 - 256 * 128)  /* XFIX_1_082392200 */
-  .short (362 * 128 - 256 * 128)  /* XFIX_1_414213562 */
-  .short (473 * 128 - 256 * 128)  /* XFIX_1_847759065 */
-  .short (669 * 128 - 512 * 128)  /* XFIX_2_613125930 */
-
-asm_function jsimd_idct_ifast_neon
-
-    DCT_TABLE       .req x0
-    COEF_BLOCK      .req x1
-    OUTPUT_BUF      .req x2
-    OUTPUT_COL      .req x3
-    TMP1            .req x0
-    TMP2            .req x1
-    TMP3            .req x9
-    TMP4            .req x10
-    TMP5            .req x11
-    TMP6            .req x12
-    TMP7            .req x13
-    TMP8            .req x14
-
-    /* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
-       guarantee that the upper (unused) 32 bits of x3 are valid.  This
-       instruction ensures that those bits are set to zero. */
-    uxtw x3, w3
-
-    /* Load and dequantize coefficients into NEON registers
-     * with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17     ( v16.8h )
-     *   1 | d18     | d19     ( v17.8h )
-     *   2 | d20     | d21     ( v18.8h )
-     *   3 | d22     | d23     ( v19.8h )
-     *   4 | d24     | d25     ( v20.8h )
-     *   5 | d26     | d27     ( v21.8h )
-     *   6 | d28     | d29     ( v22.8h )
-     *   7 | d30     | d31     ( v23.8h )
-     */
-    /* Save NEON registers used in fast IDCT */
-    adr             TMP5, Ljsimd_idct_ifast_neon_consts
-    ld1             {v16.8h, v17.8h}, [COEF_BLOCK], 32
-    ld1             {v0.8h, v1.8h}, [DCT_TABLE], 32
-    ld1             {v18.8h, v19.8h}, [COEF_BLOCK], 32
-    mul             v16.8h, v16.8h, v0.8h
-    ld1             {v2.8h, v3.8h}, [DCT_TABLE], 32
-    mul             v17.8h, v17.8h, v1.8h
-    ld1             {v20.8h, v21.8h}, [COEF_BLOCK], 32
-    mul             v18.8h, v18.8h, v2.8h
-    ld1             {v0.8h, v1.8h}, [DCT_TABLE], 32
-    mul             v19.8h, v19.8h, v3.8h
-    ld1             {v22.8h, v23.8h}, [COEF_BLOCK], 32
-    mul             v20.8h, v20.8h, v0.8h
-    ld1             {v2.8h, v3.8h}, [DCT_TABLE], 32
-    mul             v22.8h, v22.8h, v2.8h
-    mul             v21.8h, v21.8h, v1.8h
-    ld1             {v0.4h}, [TMP5]        /* load constants */
-    mul             v23.8h, v23.8h, v3.8h
-
-    /* 1-D IDCT, pass 1 */
-    sub             v2.8h, v18.8h, v22.8h
-    add             v22.8h, v18.8h, v22.8h
-    sub             v1.8h, v19.8h, v21.8h
-    add             v21.8h, v19.8h, v21.8h
-    sub             v5.8h, v17.8h, v23.8h
-    add             v23.8h, v17.8h, v23.8h
-    sqdmulh         v4.8h, v2.8h, XFIX_1_414213562
-    sqdmulh         v6.8h, v1.8h, XFIX_2_613125930
-    add             v3.8h, v1.8h, v1.8h
-    sub             v1.8h, v5.8h, v1.8h
-    add             v18.8h, v2.8h, v4.8h
-    sqdmulh         v4.8h, v1.8h, XFIX_1_847759065
-    sub             v2.8h, v23.8h, v21.8h
-    add             v3.8h, v3.8h, v6.8h
-    sqdmulh         v6.8h, v2.8h, XFIX_1_414213562
-    add             v1.8h, v1.8h, v4.8h
-    sqdmulh         v4.8h, v5.8h, XFIX_1_082392200
-    sub             v18.8h, v18.8h, v22.8h
-    add             v2.8h, v2.8h, v6.8h
-    sub             v6.8h, v16.8h, v20.8h
-    add             v20.8h, v16.8h, v20.8h
-    add             v17.8h, v5.8h, v4.8h
-    add             v5.8h, v6.8h, v18.8h
-    sub             v18.8h, v6.8h, v18.8h
-    add             v6.8h, v23.8h, v21.8h
-    add             v16.8h, v20.8h, v22.8h
-    sub             v3.8h, v6.8h, v3.8h
-    sub             v20.8h, v20.8h, v22.8h
-    sub             v3.8h, v3.8h, v1.8h
-    sub             v1.8h, v17.8h, v1.8h
-    add             v2.8h, v3.8h, v2.8h
-    sub             v23.8h, v16.8h, v6.8h
-    add             v1.8h, v1.8h, v2.8h
-    add             v16.8h, v16.8h, v6.8h
-    add             v22.8h, v5.8h, v3.8h
-    sub             v17.8h, v5.8h, v3.8h
-    sub             v21.8h, v18.8h, v2.8h
-    add             v18.8h, v18.8h, v2.8h
-    sub             v19.8h, v20.8h, v1.8h
-    add             v20.8h, v20.8h, v1.8h
-    transpose_8x8   v16, v17, v18, v19, v20, v21, v22, v23, v28, v29, v30, v31
-    /* 1-D IDCT, pass 2 */
-    sub             v2.8h, v18.8h, v22.8h
-    add             v22.8h, v18.8h, v22.8h
-    sub             v1.8h, v19.8h, v21.8h
-    add             v21.8h, v19.8h, v21.8h
-    sub             v5.8h, v17.8h, v23.8h
-    add             v23.8h, v17.8h, v23.8h
-    sqdmulh         v4.8h, v2.8h, XFIX_1_414213562
-    sqdmulh         v6.8h, v1.8h, XFIX_2_613125930
-    add             v3.8h, v1.8h, v1.8h
-    sub             v1.8h, v5.8h, v1.8h
-    add             v18.8h, v2.8h, v4.8h
-    sqdmulh         v4.8h, v1.8h, XFIX_1_847759065
-    sub             v2.8h, v23.8h, v21.8h
-    add             v3.8h, v3.8h, v6.8h
-    sqdmulh         v6.8h, v2.8h, XFIX_1_414213562
-    add             v1.8h, v1.8h, v4.8h
-    sqdmulh         v4.8h, v5.8h, XFIX_1_082392200
-    sub             v18.8h, v18.8h, v22.8h
-    add             v2.8h, v2.8h, v6.8h
-    sub             v6.8h, v16.8h, v20.8h
-    add             v20.8h, v16.8h, v20.8h
-    add             v17.8h, v5.8h, v4.8h
-    add             v5.8h, v6.8h, v18.8h
-    sub             v18.8h, v6.8h, v18.8h
-    add             v6.8h, v23.8h, v21.8h
-    add             v16.8h, v20.8h, v22.8h
-    sub             v3.8h, v6.8h, v3.8h
-    sub             v20.8h, v20.8h, v22.8h
-    sub             v3.8h, v3.8h, v1.8h
-    sub             v1.8h, v17.8h, v1.8h
-    add             v2.8h, v3.8h, v2.8h
-    sub             v23.8h, v16.8h, v6.8h
-    add             v1.8h, v1.8h, v2.8h
-    add             v16.8h, v16.8h, v6.8h
-    add             v22.8h, v5.8h, v3.8h
-    sub             v17.8h, v5.8h, v3.8h
-    sub             v21.8h, v18.8h, v2.8h
-    add             v18.8h, v18.8h, v2.8h
-    sub             v19.8h, v20.8h, v1.8h
-    add             v20.8h, v20.8h, v1.8h
-    /* Descale to 8-bit and range limit */
-    movi            v0.16b, #0x80
-      /* Prepare pointers (dual-issue with NEON instructions) */
-      ldp             TMP1, TMP2, [OUTPUT_BUF], 16
-    sqshrn          v28.8b, v16.8h, #5
-      ldp             TMP3, TMP4, [OUTPUT_BUF], 16
-    sqshrn          v29.8b, v17.8h, #5
-      add             TMP1, TMP1, OUTPUT_COL
-    sqshrn          v30.8b, v18.8h, #5
-      add             TMP2, TMP2, OUTPUT_COL
-    sqshrn          v31.8b, v19.8h, #5
-      add             TMP3, TMP3, OUTPUT_COL
-    sqshrn2         v28.16b, v20.8h, #5
-      add             TMP4, TMP4, OUTPUT_COL
-    sqshrn2         v29.16b, v21.8h, #5
-      ldp             TMP5, TMP6, [OUTPUT_BUF], 16
-    sqshrn2         v30.16b, v22.8h, #5
-      ldp             TMP7, TMP8, [OUTPUT_BUF], 16
-    sqshrn2         v31.16b, v23.8h, #5
-      add             TMP5, TMP5, OUTPUT_COL
-    add             v16.16b, v28.16b, v0.16b
-      add             TMP6, TMP6, OUTPUT_COL
-    add             v18.16b, v29.16b, v0.16b
-      add             TMP7, TMP7, OUTPUT_COL
-    add             v20.16b, v30.16b, v0.16b
-      add             TMP8, TMP8, OUTPUT_COL
-    add             v22.16b, v31.16b, v0.16b
-
-    /* Transpose the final 8-bit samples */
-    trn1            v28.16b, v16.16b, v18.16b
-    trn1            v30.16b, v20.16b, v22.16b
-    trn2            v29.16b, v16.16b, v18.16b
-    trn2            v31.16b, v20.16b, v22.16b
-
-    trn1            v16.8h, v28.8h, v30.8h
-    trn2            v18.8h, v28.8h, v30.8h
-    trn1            v20.8h, v29.8h, v31.8h
-    trn2            v22.8h, v29.8h, v31.8h
-
-    uzp1            v28.4s, v16.4s, v18.4s
-    uzp2            v30.4s, v16.4s, v18.4s
-    uzp1            v29.4s, v20.4s, v22.4s
-    uzp2            v31.4s, v20.4s, v22.4s
-
-    /* Store results to the output buffer */
-    st1             {v28.d}[0], [TMP1]
-    st1             {v29.d}[0], [TMP2]
-    st1             {v28.d}[1], [TMP3]
-    st1             {v29.d}[1], [TMP4]
-    st1             {v30.d}[0], [TMP5]
-    st1             {v31.d}[0], [TMP6]
-    st1             {v30.d}[1], [TMP7]
-    st1             {v31.d}[1], [TMP8]
-    blr             x30
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-    .unreq          TMP5
-    .unreq          TMP6
-    .unreq          TMP7
-    .unreq          TMP8
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_4x4_neon
- *
- * This function contains inverse-DCT code for getting reduced-size
- * 4x4 pixels output from an 8x8 DCT block. It uses the same  calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_4x4'
- * function from jpeg-6b (jidctred.c).
- *
- * NOTE: jpeg-8 has an improved implementation of 4x4 inverse-DCT, which
- *       requires much less arithmetic operations and hence should be faster.
- *       The primary purpose of this particular NEON optimized function is
- *       bit exact compatibility with jpeg-6b.
- *
- * TODO: a bit better instructions scheduling can be achieved by expanding
- *       idct_helper/transpose_4x4 macros and reordering instructions,
- *       but readability will suffer somewhat.
- */
-
-#define CONST_BITS  13
-
-#define FIX_0_211164243  (1730)   /* FIX(0.211164243) */
-#define FIX_0_509795579  (4176)   /* FIX(0.509795579) */
-#define FIX_0_601344887  (4926)   /* FIX(0.601344887) */
-#define FIX_0_720959822  (5906)   /* FIX(0.720959822) */
-#define FIX_0_765366865  (6270)   /* FIX(0.765366865) */
-#define FIX_0_850430095  (6967)   /* FIX(0.850430095) */
-#define FIX_0_899976223  (7373)   /* FIX(0.899976223) */
-#define FIX_1_061594337  (8697)   /* FIX(1.061594337) */
-#define FIX_1_272758580  (10426)  /* FIX(1.272758580) */
-#define FIX_1_451774981  (11893)  /* FIX(1.451774981) */
-#define FIX_1_847759065  (15137)  /* FIX(1.847759065) */
-#define FIX_2_172734803  (17799)  /* FIX(2.172734803) */
-#define FIX_2_562915447  (20995)  /* FIX(2.562915447) */
-#define FIX_3_624509785  (29692)  /* FIX(3.624509785) */
-
-.balign 16
-Ljsimd_idct_4x4_neon_consts:
-  .short FIX_1_847759065        /* v0.h[0] */
-  .short -FIX_0_765366865       /* v0.h[1] */
-  .short -FIX_0_211164243       /* v0.h[2] */
-  .short FIX_1_451774981        /* v0.h[3] */
-  .short -FIX_2_172734803       /* d1[0] */
-  .short FIX_1_061594337        /* d1[1] */
-  .short -FIX_0_509795579       /* d1[2] */
-  .short -FIX_0_601344887       /* d1[3] */
-  .short FIX_0_899976223        /* v2.h[0] */
-  .short FIX_2_562915447        /* v2.h[1] */
-  .short 1 << (CONST_BITS + 1)  /* v2.h[2] */
-  .short 0                      /* v2.h[3] */
-
-.macro idct_helper x4, x6, x8, x10, x12, x14, x16, shift, y26, y27, y28, y29
-    smull           v28.4s, \x4, v2.h[2]
-    smlal           v28.4s, \x8, v0.h[0]
-    smlal           v28.4s, \x14, v0.h[1]
-
-    smull           v26.4s, \x16, v1.h[2]
-    smlal           v26.4s, \x12, v1.h[3]
-    smlal           v26.4s, \x10, v2.h[0]
-    smlal           v26.4s, \x6, v2.h[1]
-
-    smull           v30.4s, \x4, v2.h[2]
-    smlsl           v30.4s, \x8, v0.h[0]
-    smlsl           v30.4s, \x14, v0.h[1]
-
-    smull           v24.4s, \x16, v0.h[2]
-    smlal           v24.4s, \x12, v0.h[3]
-    smlal           v24.4s, \x10, v1.h[0]
-    smlal           v24.4s, \x6, v1.h[1]
-
-    add             v20.4s, v28.4s, v26.4s
-    sub             v28.4s, v28.4s, v26.4s
-
-  .if \shift > 16
-    srshr           v20.4s, v20.4s, #\shift
-    srshr           v28.4s, v28.4s, #\shift
-    xtn             \y26, v20.4s
-    xtn             \y29, v28.4s
-  .else
-    rshrn           \y26, v20.4s, #\shift
-    rshrn           \y29, v28.4s, #\shift
-  .endif
-
-    add             v20.4s, v30.4s, v24.4s
-    sub             v30.4s, v30.4s, v24.4s
-
-  .if \shift > 16
-    srshr           v20.4s, v20.4s, #\shift
-    srshr           v30.4s, v30.4s, #\shift
-    xtn             \y27, v20.4s
-    xtn             \y28, v30.4s
-  .else
-    rshrn           \y27, v20.4s, #\shift
-    rshrn           \y28, v30.4s, #\shift
-  .endif
-.endm
-
-asm_function jsimd_idct_4x4_neon
-
-    DCT_TABLE       .req x0
-    COEF_BLOCK      .req x1
-    OUTPUT_BUF      .req x2
-    OUTPUT_COL      .req x3
-    TMP1            .req x0
-    TMP2            .req x1
-    TMP3            .req x2
-    TMP4            .req x15
-
-    /* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
-       guarantee that the upper (unused) 32 bits of x3 are valid.  This
-       instruction ensures that those bits are set to zero. */
-    uxtw x3, w3
-
-    /* Save all used NEON registers */
-    sub             sp, sp, 64
-    mov             x9, sp
-    /* Load constants (v3.4h is just used for padding) */
-    adr             TMP4, Ljsimd_idct_4x4_neon_consts
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
-    ld1             {v0.4h, v1.4h, v2.4h, v3.4h}, [TMP4]
-
-    /* Load all COEF_BLOCK into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | v4.4h   | v5.4h
-     *   1 | v6.4h   | v7.4h
-     *   2 | v8.4h   | v9.4h
-     *   3 | v10.4h  | v11.4h
-     *   4 | -       | -
-     *   5 | v12.4h  | v13.4h
-     *   6 | v14.4h  | v15.4h
-     *   7 | v16.4h  | v17.4h
-     */
-    ld1             {v4.4h, v5.4h, v6.4h, v7.4h}, [COEF_BLOCK], 32
-    ld1             {v8.4h, v9.4h, v10.4h, v11.4h}, [COEF_BLOCK], 32
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    ld1             {v12.4h, v13.4h, v14.4h, v15.4h}, [COEF_BLOCK], 32
-    ld1             {v16.4h, v17.4h}, [COEF_BLOCK], 16
-    /* dequantize */
-    ld1             {v18.4h, v19.4h, v20.4h, v21.4h}, [DCT_TABLE], 32
-    mul             v4.4h, v4.4h, v18.4h
-    mul             v5.4h, v5.4h, v19.4h
-    ins             v4.d[1], v5.d[0]              /* 128 bit q4 */
-    ld1             {v22.4h, v23.4h, v24.4h, v25.4h}, [DCT_TABLE], 32
-    mul             v6.4h, v6.4h, v20.4h
-    mul             v7.4h, v7.4h, v21.4h
-    ins             v6.d[1], v7.d[0]              /* 128 bit q6 */
-    mul             v8.4h, v8.4h, v22.4h
-    mul             v9.4h, v9.4h, v23.4h
-    ins             v8.d[1], v9.d[0]              /* 128 bit q8 */
-    add             DCT_TABLE, DCT_TABLE, #16
-    ld1             {v26.4h, v27.4h, v28.4h, v29.4h}, [DCT_TABLE], 32
-    mul             v10.4h, v10.4h, v24.4h
-    mul             v11.4h, v11.4h, v25.4h
-    ins             v10.d[1], v11.d[0]            /* 128 bit q10 */
-    mul             v12.4h, v12.4h, v26.4h
-    mul             v13.4h, v13.4h, v27.4h
-    ins             v12.d[1], v13.d[0]            /* 128 bit q12 */
-    ld1             {v30.4h, v31.4h}, [DCT_TABLE], 16
-    mul             v14.4h, v14.4h, v28.4h
-    mul             v15.4h, v15.4h, v29.4h
-    ins             v14.d[1], v15.d[0]            /* 128 bit q14 */
-    mul             v16.4h, v16.4h, v30.4h
-    mul             v17.4h, v17.4h, v31.4h
-    ins             v16.d[1], v17.d[0]            /* 128 bit q16 */
-
-    /* Pass 1 */
-    idct_helper     v4.4h, v6.4h, v8.4h, v10.4h, v12.4h, v14.4h, v16.4h, 12, \
-                    v4.4h, v6.4h, v8.4h, v10.4h
-    transpose_4x4   v4, v6, v8, v10, v3
-    ins             v10.d[1], v11.d[0]
-    idct_helper     v5.4h, v7.4h, v9.4h, v11.4h, v13.4h, v15.4h, v17.4h, 12, \
-                    v5.4h, v7.4h, v9.4h, v11.4h
-    transpose_4x4   v5, v7, v9, v11, v3
-    ins             v10.d[1], v11.d[0]
-
-    /* Pass 2 */
-    idct_helper     v4.4h, v6.4h, v8.4h, v10.4h, v7.4h, v9.4h, v11.4h, 19, \
-                    v26.4h, v27.4h, v28.4h, v29.4h
-    transpose_4x4   v26, v27, v28, v29, v3
-
-    /* Range limit */
-    movi            v30.8h, #0x80
-    ins             v26.d[1], v27.d[0]
-    ins             v28.d[1], v29.d[0]
-    add             v26.8h, v26.8h, v30.8h
-    add             v28.8h, v28.8h, v30.8h
-    sqxtun          v26.8b, v26.8h
-    sqxtun          v27.8b, v28.8h
-
-    /* Store results to the output buffer */
-    ldp             TMP1, TMP2, [OUTPUT_BUF], 16
-    ldp             TMP3, TMP4, [OUTPUT_BUF]
-    add             TMP1, TMP1, OUTPUT_COL
-    add             TMP2, TMP2, OUTPUT_COL
-    add             TMP3, TMP3, OUTPUT_COL
-    add             TMP4, TMP4, OUTPUT_COL
-
-#if defined(__ARMEL__) && !RESPECT_STRICT_ALIGNMENT
-    /* We can use much less instructions on little endian systems if the
-     * OS kernel is not configured to trap unaligned memory accesses
-     */
-    st1             {v26.s}[0], [TMP1], 4
-    st1             {v27.s}[0], [TMP3], 4
-    st1             {v26.s}[1], [TMP2], 4
-    st1             {v27.s}[1], [TMP4], 4
-#else
-    st1             {v26.b}[0], [TMP1], 1
-    st1             {v27.b}[0], [TMP3], 1
-    st1             {v26.b}[1], [TMP1], 1
-    st1             {v27.b}[1], [TMP3], 1
-    st1             {v26.b}[2], [TMP1], 1
-    st1             {v27.b}[2], [TMP3], 1
-    st1             {v26.b}[3], [TMP1], 1
-    st1             {v27.b}[3], [TMP3], 1
-
-    st1             {v26.b}[4], [TMP2], 1
-    st1             {v27.b}[4], [TMP4], 1
-    st1             {v26.b}[5], [TMP2], 1
-    st1             {v27.b}[5], [TMP4], 1
-    st1             {v26.b}[6], [TMP2], 1
-    st1             {v27.b}[6], [TMP4], 1
-    st1             {v26.b}[7], [TMP2], 1
-    st1             {v27.b}[7], [TMP4], 1
-#endif
-
-    /* vpop            {v8.4h - v15.4h}    ;not available */
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
-    blr             x30
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-
-.purgem idct_helper
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_idct_2x2_neon
- *
- * This function contains inverse-DCT code for getting reduced-size
- * 2x2 pixels output from an 8x8 DCT block. It uses the same  calculations
- * and produces exactly the same output as IJG's original 'jpeg_idct_2x2'
- * function from jpeg-6b (jidctred.c).
- *
- * NOTE: jpeg-8 has an improved implementation of 2x2 inverse-DCT, which
- *       requires much less arithmetic operations and hence should be faster.
- *       The primary purpose of this particular NEON optimized function is
- *       bit exact compatibility with jpeg-6b.
- */
-
-.balign 8
-Ljsimd_idct_2x2_neon_consts:
-  .short -FIX_0_720959822  /* v14[0] */
-  .short FIX_0_850430095   /* v14[1] */
-  .short -FIX_1_272758580  /* v14[2] */
-  .short FIX_3_624509785   /* v14[3] */
-
-.macro idct_helper x4, x6, x10, x12, x16, shift, y26, y27
-    sshll           v15.4s, \x4, #15
-    smull           v26.4s, \x6, v14.h[3]
-    smlal           v26.4s, \x10, v14.h[2]
-    smlal           v26.4s, \x12, v14.h[1]
-    smlal           v26.4s, \x16, v14.h[0]
-
-    add             v20.4s, v15.4s, v26.4s
-    sub             v15.4s, v15.4s, v26.4s
-
-  .if \shift > 16
-    srshr           v20.4s, v20.4s, #\shift
-    srshr           v15.4s, v15.4s, #\shift
-    xtn             \y26, v20.4s
-    xtn             \y27, v15.4s
-  .else
-    rshrn           \y26, v20.4s, #\shift
-    rshrn           \y27, v15.4s, #\shift
-  .endif
-.endm
-
-asm_function jsimd_idct_2x2_neon
-
-    DCT_TABLE       .req x0
-    COEF_BLOCK      .req x1
-    OUTPUT_BUF      .req x2
-    OUTPUT_COL      .req x3
-    TMP1            .req x0
-    TMP2            .req x15
-
-    /* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
-       guarantee that the upper (unused) 32 bits of x3 are valid.  This
-       instruction ensures that those bits are set to zero. */
-    uxtw x3, w3
-
-    /* vpush           {v8.4h - v15.4h}            ; not available */
-    sub             sp, sp, 64
-    mov             x9, sp
-
-    /* Load constants */
-    adr             TMP2, Ljsimd_idct_2x2_neon_consts
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
-    ld1             {v14.4h}, [TMP2]
-
-    /* Load all COEF_BLOCK into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | v4.4h   | v5.4h
-     *   1 | v6.4h   | v7.4h
-     *   2 | -       | -
-     *   3 | v10.4h  | v11.4h
-     *   4 | -       | -
-     *   5 | v12.4h  | v13.4h
-     *   6 | -       | -
-     *   7 | v16.4h  | v17.4h
-     */
-    ld1             {v4.4h, v5.4h, v6.4h, v7.4h}, [COEF_BLOCK], 32
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    ld1             {v10.4h, v11.4h}, [COEF_BLOCK], 16
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    ld1             {v12.4h, v13.4h}, [COEF_BLOCK], 16
-    add             COEF_BLOCK, COEF_BLOCK, #16
-    ld1             {v16.4h, v17.4h}, [COEF_BLOCK], 16
-    /* Dequantize */
-    ld1             {v18.4h, v19.4h, v20.4h, v21.4h}, [DCT_TABLE], 32
-    mul             v4.4h, v4.4h, v18.4h
-    mul             v5.4h, v5.4h, v19.4h
-    ins             v4.d[1], v5.d[0]
-    mul             v6.4h, v6.4h, v20.4h
-    mul             v7.4h, v7.4h, v21.4h
-    ins             v6.d[1], v7.d[0]
-    add             DCT_TABLE, DCT_TABLE, #16
-    ld1             {v24.4h, v25.4h}, [DCT_TABLE], 16
-    mul             v10.4h, v10.4h, v24.4h
-    mul             v11.4h, v11.4h, v25.4h
-    ins             v10.d[1], v11.d[0]
-    add             DCT_TABLE, DCT_TABLE, #16
-    ld1             {v26.4h, v27.4h}, [DCT_TABLE], 16
-    mul             v12.4h, v12.4h, v26.4h
-    mul             v13.4h, v13.4h, v27.4h
-    ins             v12.d[1], v13.d[0]
-    add             DCT_TABLE, DCT_TABLE, #16
-    ld1             {v30.4h, v31.4h}, [DCT_TABLE], 16
-    mul             v16.4h, v16.4h, v30.4h
-    mul             v17.4h, v17.4h, v31.4h
-    ins             v16.d[1], v17.d[0]
-
-    /* Pass 1 */
-#if 0
-    idct_helper     v4.4h, v6.4h, v10.4h, v12.4h, v16.4h, 13, v4.4h, v6.4h
-    transpose_4x4   v4.4h, v6.4h, v8.4h, v10.4h
-    idct_helper     v5.4h, v7.4h, v11.4h, v13.4h, v17.4h, 13, v5.4h, v7.4h
-    transpose_4x4   v5.4h, v7.4h, v9.4h, v11.4h
-#else
-    smull           v26.4s, v6.4h, v14.h[3]
-    smlal           v26.4s, v10.4h, v14.h[2]
-    smlal           v26.4s, v12.4h, v14.h[1]
-    smlal           v26.4s, v16.4h, v14.h[0]
-    smull           v24.4s, v7.4h, v14.h[3]
-    smlal           v24.4s, v11.4h, v14.h[2]
-    smlal           v24.4s, v13.4h, v14.h[1]
-    smlal           v24.4s, v17.4h, v14.h[0]
-    sshll           v15.4s, v4.4h, #15
-    sshll           v30.4s, v5.4h, #15
-    add             v20.4s, v15.4s, v26.4s
-    sub             v15.4s, v15.4s, v26.4s
-    rshrn           v4.4h, v20.4s, #13
-    rshrn           v6.4h, v15.4s, #13
-    add             v20.4s, v30.4s, v24.4s
-    sub             v15.4s, v30.4s, v24.4s
-    rshrn           v5.4h, v20.4s, #13
-    rshrn           v7.4h, v15.4s, #13
-    ins             v4.d[1], v5.d[0]
-    ins             v6.d[1], v7.d[0]
-    transpose       v4, v6, v3, .16b, .8h
-    transpose       v6, v10, v3, .16b, .4s
-    ins             v11.d[0], v10.d[1]
-    ins             v7.d[0], v6.d[1]
-#endif
-
-    /* Pass 2 */
-    idct_helper     v4.4h, v6.4h, v10.4h, v7.4h, v11.4h, 20, v26.4h, v27.4h
-
-    /* Range limit */
-    movi            v30.8h, #0x80
-    ins             v26.d[1], v27.d[0]
-    add             v26.8h, v26.8h, v30.8h
-    sqxtun          v30.8b, v26.8h
-    ins             v26.d[0], v30.d[0]
-    sqxtun          v27.8b, v26.8h
-
-    /* Store results to the output buffer */
-    ldp             TMP1, TMP2, [OUTPUT_BUF]
-    add             TMP1, TMP1, OUTPUT_COL
-    add             TMP2, TMP2, OUTPUT_COL
-
-    st1             {v26.b}[0], [TMP1], 1
-    st1             {v27.b}[4], [TMP1], 1
-    st1             {v26.b}[1], [TMP2], 1
-    st1             {v27.b}[5], [TMP2], 1
-
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
-    blr             x30
-
-    .unreq          DCT_TABLE
-    .unreq          COEF_BLOCK
-    .unreq          OUTPUT_BUF
-    .unreq          OUTPUT_COL
-    .unreq          TMP1
-    .unreq          TMP2
-
-.purgem idct_helper
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_ycc_extrgb_convert_neon
- * jsimd_ycc_extbgr_convert_neon
- * jsimd_ycc_extrgbx_convert_neon
- * jsimd_ycc_extbgrx_convert_neon
- * jsimd_ycc_extxbgr_convert_neon
- * jsimd_ycc_extxrgb_convert_neon
- *
- * Colorspace conversion YCbCr -> RGB
- */
-
-.macro do_load size
-  .if \size == 8
-    ld1             {v4.8b}, [U], 8
-    ld1             {v5.8b}, [V], 8
-    ld1             {v0.8b}, [Y], 8
-    prfm            pldl1keep, [U, #64]
-    prfm            pldl1keep, [V, #64]
-    prfm            pldl1keep, [Y, #64]
-  .elseif \size == 4
-    ld1             {v4.b}[0], [U], 1
-    ld1             {v4.b}[1], [U], 1
-    ld1             {v4.b}[2], [U], 1
-    ld1             {v4.b}[3], [U], 1
-    ld1             {v5.b}[0], [V], 1
-    ld1             {v5.b}[1], [V], 1
-    ld1             {v5.b}[2], [V], 1
-    ld1             {v5.b}[3], [V], 1
-    ld1             {v0.b}[0], [Y], 1
-    ld1             {v0.b}[1], [Y], 1
-    ld1             {v0.b}[2], [Y], 1
-    ld1             {v0.b}[3], [Y], 1
-  .elseif \size == 2
-    ld1             {v4.b}[4], [U], 1
-    ld1             {v4.b}[5], [U], 1
-    ld1             {v5.b}[4], [V], 1
-    ld1             {v5.b}[5], [V], 1
-    ld1             {v0.b}[4], [Y], 1
-    ld1             {v0.b}[5], [Y], 1
-  .elseif \size == 1
-    ld1             {v4.b}[6], [U], 1
-    ld1             {v5.b}[6], [V], 1
-    ld1             {v0.b}[6], [Y], 1
-  .else
-    .error unsupported macroblock size
-  .endif
-.endm
-
-.macro do_store bpp, size, fast_st3
-  .if \bpp == 24
-    .if \size == 8
-      .if \fast_st3 == 1
-        st3         {v10.8b, v11.8b, v12.8b}, [RGB], 24
-      .else
-        st1         {v10.b}[0], [RGB], #1
-        st1         {v11.b}[0], [RGB], #1
-        st1         {v12.b}[0], [RGB], #1
-
-        st1         {v10.b}[1], [RGB], #1
-        st1         {v11.b}[1], [RGB], #1
-        st1         {v12.b}[1], [RGB], #1
-
-        st1         {v10.b}[2], [RGB], #1
-        st1         {v11.b}[2], [RGB], #1
-        st1         {v12.b}[2], [RGB], #1
-
-        st1         {v10.b}[3], [RGB], #1
-        st1         {v11.b}[3], [RGB], #1
-        st1         {v12.b}[3], [RGB], #1
-
-        st1         {v10.b}[4], [RGB], #1
-        st1         {v11.b}[4], [RGB], #1
-        st1         {v12.b}[4], [RGB], #1
-
-        st1         {v10.b}[5], [RGB], #1
-        st1         {v11.b}[5], [RGB], #1
-        st1         {v12.b}[5], [RGB], #1
-
-        st1         {v10.b}[6], [RGB], #1
-        st1         {v11.b}[6], [RGB], #1
-        st1         {v12.b}[6], [RGB], #1
-
-        st1         {v10.b}[7], [RGB], #1
-        st1         {v11.b}[7], [RGB], #1
-        st1         {v12.b}[7], [RGB], #1
-      .endif
-    .elseif \size == 4
-      st3           {v10.b, v11.b, v12.b}[0], [RGB], 3
-      st3           {v10.b, v11.b, v12.b}[1], [RGB], 3
-      st3           {v10.b, v11.b, v12.b}[2], [RGB], 3
-      st3           {v10.b, v11.b, v12.b}[3], [RGB], 3
-    .elseif \size == 2
-      st3           {v10.b, v11.b, v12.b}[4], [RGB], 3
-      st3           {v10.b, v11.b, v12.b}[5], [RGB], 3
-    .elseif \size == 1
-      st3           {v10.b, v11.b, v12.b}[6], [RGB], 3
-    .else
-     .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 32
-    .if \size == 8
-      st4           {v10.8b, v11.8b, v12.8b, v13.8b}, [RGB], 32
-    .elseif \size == 4
-      st4           {v10.b, v11.b, v12.b, v13.b}[0], [RGB], 4
-      st4           {v10.b, v11.b, v12.b, v13.b}[1], [RGB], 4
-      st4           {v10.b, v11.b, v12.b, v13.b}[2], [RGB], 4
-      st4           {v10.b, v11.b, v12.b, v13.b}[3], [RGB], 4
-    .elseif \size == 2
-      st4           {v10.b, v11.b, v12.b, v13.b}[4], [RGB], 4
-      st4           {v10.b, v11.b, v12.b, v13.b}[5], [RGB], 4
-    .elseif \size == 1
-      st4           {v10.b, v11.b, v12.b, v13.b}[6], [RGB], 4
-    .else
-      .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 16
-    .if \size == 8
-      st1           {v25.8h}, [RGB], 16
-    .elseif \size == 4
-      st1           {v25.4h}, [RGB], 8
-    .elseif \size == 2
-      st1           {v25.h}[4], [RGB], 2
-      st1           {v25.h}[5], [RGB], 2
-    .elseif \size == 1
-      st1           {v25.h}[6], [RGB], 2
-    .else
-      .error unsupported macroblock size
-    .endif
-  .else
-    .error unsupported bpp
-  .endif
-.endm
-
-.macro generate_jsimd_ycc_rgb_convert_neon colorid, bpp, r_offs, rsize, \
-                                           g_offs, gsize, b_offs, bsize, \
-                                           defsize, fast_st3
-
-/*
- * 2-stage pipelined YCbCr->RGB conversion
- */
-
-.macro do_yuv_to_rgb_stage1
-    uaddw           v6.8h, v2.8h, v4.8b     /* q3 = u - 128 */
-    uaddw           v8.8h, v2.8h, v5.8b     /* q2 = v - 128 */
-    smull           v20.4s, v6.4h, v1.h[1]  /* multiply by -11277 */
-    smlal           v20.4s, v8.4h, v1.h[2]  /* multiply by -23401 */
-    smull2          v22.4s, v6.8h, v1.h[1]  /* multiply by -11277 */
-    smlal2          v22.4s, v8.8h, v1.h[2]  /* multiply by -23401 */
-    smull           v24.4s, v8.4h, v1.h[0]  /* multiply by 22971 */
-    smull2          v26.4s, v8.8h, v1.h[0]  /* multiply by 22971 */
-    smull           v28.4s, v6.4h, v1.h[3]  /* multiply by 29033 */
-    smull2          v30.4s, v6.8h, v1.h[3]  /* multiply by 29033 */
-.endm
-
-.macro do_yuv_to_rgb_stage2
-    rshrn           v20.4h, v20.4s, #15
-    rshrn2          v20.8h, v22.4s, #15
-    rshrn           v24.4h, v24.4s, #14
-    rshrn2          v24.8h, v26.4s, #14
-    rshrn           v28.4h, v28.4s, #14
-    rshrn2          v28.8h, v30.4s, #14
-    uaddw           v20.8h, v20.8h, v0.8b
-    uaddw           v24.8h, v24.8h, v0.8b
-    uaddw           v28.8h, v28.8h, v0.8b
-  .if \bpp != 16
-    sqxtun          v1\g_offs\defsize, v20.8h
-    sqxtun          v1\r_offs\defsize, v24.8h
-    sqxtun          v1\b_offs\defsize, v28.8h
-  .else
-    sqshlu          v21.8h, v20.8h, #8
-    sqshlu          v25.8h, v24.8h, #8
-    sqshlu          v29.8h, v28.8h, #8
-    sri             v25.8h, v21.8h, #5
-    sri             v25.8h, v29.8h, #11
-  .endif
-.endm
-
-.macro do_yuv_to_rgb_stage2_store_load_stage1 fast_st3
-    rshrn           v20.4h, v20.4s, #15
-    rshrn           v24.4h, v24.4s, #14
-    rshrn           v28.4h, v28.4s, #14
-    ld1             {v4.8b}, [U], 8
-    rshrn2          v20.8h, v22.4s, #15
-    rshrn2          v24.8h, v26.4s, #14
-    rshrn2          v28.8h, v30.4s, #14
-    ld1             {v5.8b}, [V], 8
-    uaddw           v20.8h, v20.8h, v0.8b
-    uaddw           v24.8h, v24.8h, v0.8b
-    uaddw           v28.8h, v28.8h, v0.8b
-  .if \bpp != 16  /**************** rgb24/rgb32 ******************************/
-    sqxtun          v1\g_offs\defsize, v20.8h
-    ld1             {v0.8b}, [Y], 8
-    sqxtun          v1\r_offs\defsize, v24.8h
-    prfm            pldl1keep, [U, #64]
-    prfm            pldl1keep, [V, #64]
-    prfm            pldl1keep, [Y, #64]
-    sqxtun          v1\b_offs\defsize, v28.8h
-    uaddw           v6.8h, v2.8h, v4.8b     /* v6.16b = u - 128 */
-    uaddw           v8.8h, v2.8h, v5.8b     /* q2 = v - 128 */
-    smull           v20.4s, v6.4h, v1.h[1]  /* multiply by -11277 */
-    smlal           v20.4s, v8.4h, v1.h[2]  /* multiply by -23401 */
-    smull2          v22.4s, v6.8h, v1.h[1]  /* multiply by -11277 */
-    smlal2          v22.4s, v8.8h, v1.h[2]  /* multiply by -23401 */
-    smull           v24.4s, v8.4h, v1.h[0]  /* multiply by 22971 */
-    smull2          v26.4s, v8.8h, v1.h[0]  /* multiply by 22971 */
-  .else  /**************************** rgb565 ********************************/
-    sqshlu          v21.8h, v20.8h, #8
-    sqshlu          v25.8h, v24.8h, #8
-    sqshlu          v29.8h, v28.8h, #8
-    uaddw           v6.8h, v2.8h, v4.8b     /* v6.16b = u - 128 */
-    uaddw           v8.8h, v2.8h, v5.8b     /* q2 = v - 128 */
-    ld1             {v0.8b}, [Y], 8
-    smull           v20.4s, v6.4h, v1.h[1]  /* multiply by -11277 */
-    smlal           v20.4s, v8.4h, v1.h[2]  /* multiply by -23401 */
-    smull2          v22.4s, v6.8h, v1.h[1]  /* multiply by -11277 */
-    smlal2          v22.4s, v8.8h, v1.h[2]  /* multiply by -23401 */
-    sri             v25.8h, v21.8h, #5
-    smull           v24.4s, v8.4h, v1.h[0]  /* multiply by 22971 */
-    smull2          v26.4s, v8.8h, v1.h[0]  /* multiply by 22971 */
-    prfm            pldl1keep, [U, #64]
-    prfm            pldl1keep, [V, #64]
-    prfm            pldl1keep, [Y, #64]
-    sri             v25.8h, v29.8h, #11
-  .endif
-    do_store        \bpp, 8, \fast_st3
-    smull           v28.4s, v6.4h, v1.h[3]  /* multiply by 29033 */
-    smull2          v30.4s, v6.8h, v1.h[3]  /* multiply by 29033 */
-.endm
-
-.macro do_yuv_to_rgb
-    do_yuv_to_rgb_stage1
-    do_yuv_to_rgb_stage2
-.endm
-
-/* Apple gas crashes on adrl, work around that by using adr.
- * But this requires a copy of these constants for each function.
- */
-
-.balign 16
-.if \fast_st3 == 1
-Ljsimd_ycc_\colorid\()_neon_consts:
-.else
-Ljsimd_ycc_\colorid\()_neon_slowst3_consts:
-.endif
-  .short 0,      0,     0,      0
-  .short 22971, -11277, -23401, 29033
-  .short -128,  -128,   -128,   -128
-  .short -128,  -128,   -128,   -128
-
-.if \fast_st3 == 1
-asm_function jsimd_ycc_\colorid\()_convert_neon
-.else
-asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3
-.endif
-    OUTPUT_WIDTH    .req w0
-    INPUT_BUF       .req x1
-    INPUT_ROW       .req w2
-    OUTPUT_BUF      .req x3
-    NUM_ROWS        .req w4
-
-    INPUT_BUF0      .req x5
-    INPUT_BUF1      .req x6
-    INPUT_BUF2      .req x1
-
-    RGB             .req x7
-    Y               .req x9
-    U               .req x10
-    V               .req x11
-    N               .req w15
-
-    sub             sp, sp, 64
-    mov             x9, sp
-
-    /* Load constants to d1, d2, d3 (v0.4h is just used for padding) */
-    .if \fast_st3 == 1
-      adr           x15, Ljsimd_ycc_\colorid\()_neon_consts
-    .else
-      adr           x15, Ljsimd_ycc_\colorid\()_neon_slowst3_consts
-    .endif
-
-    /* Save NEON registers */
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
-    ld1             {v0.4h, v1.4h}, [x15], 16
-    ld1             {v2.8h}, [x15]
-
-    ldr             INPUT_BUF0, [INPUT_BUF]
-    ldr             INPUT_BUF1, [INPUT_BUF, #8]
-    ldr             INPUT_BUF2, [INPUT_BUF, #16]
-    .unreq          INPUT_BUF
-
-    /* Initially set v10, v11.4h, v12.8b, d13 to 0xFF */
-    movi            v10.16b, #255
-    movi            v13.16b, #255
-
-    /* Outer loop over scanlines */
-    cmp             NUM_ROWS, #1
-    b.lt            9f
-0:
-    ldr             Y, [INPUT_BUF0, INPUT_ROW, uxtw #3]
-    ldr             U, [INPUT_BUF1, INPUT_ROW, uxtw #3]
-    mov             N, OUTPUT_WIDTH
-    ldr             V, [INPUT_BUF2, INPUT_ROW, uxtw #3]
-    add             INPUT_ROW, INPUT_ROW, #1
-    ldr             RGB, [OUTPUT_BUF], #8
-
-    /* Inner loop over pixels */
-    subs            N, N, #8
-    b.lt            3f
-    do_load         8
-    do_yuv_to_rgb_stage1
-    subs            N, N, #8
-    b.lt            2f
-1:
-    do_yuv_to_rgb_stage2_store_load_stage1 \fast_st3
-    subs            N, N, #8
-    b.ge            1b
-2:
-    do_yuv_to_rgb_stage2
-    do_store        \bpp, 8, \fast_st3
-    tst             N, #7
-    b.eq            8f
-3:
-    tst             N, #4
-    b.eq            3f
-    do_load         4
-3:
-    tst             N, #2
-    b.eq            4f
-    do_load         2
-4:
-    tst             N, #1
-    b.eq            5f
-    do_load         1
-5:
-    do_yuv_to_rgb
-    tst             N, #4
-    b.eq            6f
-    do_store        \bpp, 4, \fast_st3
-6:
-    tst             N, #2
-    b.eq            7f
-    do_store        \bpp, 2, \fast_st3
-7:
-    tst             N, #1
-    b.eq            8f
-    do_store        \bpp, 1, \fast_st3
-8:
-    subs            NUM_ROWS, NUM_ROWS, #1
-    b.gt            0b
-9:
-    /* Restore all registers and return */
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
-    br              x30
-    .unreq          OUTPUT_WIDTH
-    .unreq          INPUT_ROW
-    .unreq          OUTPUT_BUF
-    .unreq          NUM_ROWS
-    .unreq          INPUT_BUF0
-    .unreq          INPUT_BUF1
-    .unreq          INPUT_BUF2
-    .unreq          RGB
-    .unreq          Y
-    .unreq          U
-    .unreq          V
-    .unreq          N
-
-.purgem do_yuv_to_rgb
-.purgem do_yuv_to_rgb_stage1
-.purgem do_yuv_to_rgb_stage2
-.purgem do_yuv_to_rgb_stage2_store_load_stage1
-
-.endm
-
-/*--------------------------------- id ----- bpp R  rsize G  gsize B  bsize defsize fast_st3*/
-generate_jsimd_ycc_rgb_convert_neon extrgb,  24, 0, .4h,  1, .4h,  2, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon extbgr,  24, 2, .4h,  1, .4h,  0, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon extrgbx, 32, 0, .4h,  1, .4h,  2, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon extbgrx, 32, 2, .4h,  1, .4h,  0, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon extxbgr, 32, 3, .4h,  2, .4h,  1, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon extxrgb, 32, 1, .4h,  2, .4h,  3, .4h,  .8b,    1
-generate_jsimd_ycc_rgb_convert_neon rgb565,  16, 0, .4h,  0, .4h,  0, .4h,  .8b,    1
-
-generate_jsimd_ycc_rgb_convert_neon extrgb,  24, 0, .4h,  1, .4h,  2, .4h,  .8b,    0
-generate_jsimd_ycc_rgb_convert_neon extbgr,  24, 2, .4h,  1, .4h,  0, .4h,  .8b,    0
-
-.purgem do_load
-.purgem do_store
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_extrgb_ycc_convert_neon
- * jsimd_extbgr_ycc_convert_neon
- * jsimd_extrgbx_ycc_convert_neon
- * jsimd_extbgrx_ycc_convert_neon
- * jsimd_extxbgr_ycc_convert_neon
- * jsimd_extxrgb_ycc_convert_neon
- *
- * Colorspace conversion RGB -> YCbCr
- */
-
-.macro do_store size
-  .if \size == 8
-    st1             {v20.8b}, [Y], #8
-    st1             {v21.8b}, [U], #8
-    st1             {v22.8b}, [V], #8
-  .elseif \size == 4
-    st1             {v20.b}[0], [Y], #1
-    st1             {v20.b}[1], [Y], #1
-    st1             {v20.b}[2], [Y], #1
-    st1             {v20.b}[3], [Y], #1
-    st1             {v21.b}[0], [U], #1
-    st1             {v21.b}[1], [U], #1
-    st1             {v21.b}[2], [U], #1
-    st1             {v21.b}[3], [U], #1
-    st1             {v22.b}[0], [V], #1
-    st1             {v22.b}[1], [V], #1
-    st1             {v22.b}[2], [V], #1
-    st1             {v22.b}[3], [V], #1
-  .elseif \size == 2
-    st1             {v20.b}[4], [Y], #1
-    st1             {v20.b}[5], [Y], #1
-    st1             {v21.b}[4], [U], #1
-    st1             {v21.b}[5], [U], #1
-    st1             {v22.b}[4], [V], #1
-    st1             {v22.b}[5], [V], #1
-  .elseif \size == 1
-    st1             {v20.b}[6], [Y], #1
-    st1             {v21.b}[6], [U], #1
-    st1             {v22.b}[6], [V], #1
-  .else
-    .error unsupported macroblock size
-  .endif
-.endm
-
-.macro do_load bpp, size, fast_ld3
-  .if \bpp == 24
-    .if \size == 8
-      .if \fast_ld3 == 1
-        ld3         {v10.8b, v11.8b, v12.8b}, [RGB], #24
-      .else
-        ld1         {v10.b}[0], [RGB], #1
-        ld1         {v11.b}[0], [RGB], #1
-        ld1         {v12.b}[0], [RGB], #1
-
-        ld1         {v10.b}[1], [RGB], #1
-        ld1         {v11.b}[1], [RGB], #1
-        ld1         {v12.b}[1], [RGB], #1
-
-        ld1         {v10.b}[2], [RGB], #1
-        ld1         {v11.b}[2], [RGB], #1
-        ld1         {v12.b}[2], [RGB], #1
-
-        ld1         {v10.b}[3], [RGB], #1
-        ld1         {v11.b}[3], [RGB], #1
-        ld1         {v12.b}[3], [RGB], #1
-
-        ld1         {v10.b}[4], [RGB], #1
-        ld1         {v11.b}[4], [RGB], #1
-        ld1         {v12.b}[4], [RGB], #1
-
-        ld1         {v10.b}[5], [RGB], #1
-        ld1         {v11.b}[5], [RGB], #1
-        ld1         {v12.b}[5], [RGB], #1
-
-        ld1         {v10.b}[6], [RGB], #1
-        ld1         {v11.b}[6], [RGB], #1
-        ld1         {v12.b}[6], [RGB], #1
-
-        ld1         {v10.b}[7], [RGB], #1
-        ld1         {v11.b}[7], [RGB], #1
-        ld1         {v12.b}[7], [RGB], #1
-      .endif
-      prfm          pldl1keep, [RGB, #128]
-    .elseif \size == 4
-      ld3           {v10.b, v11.b, v12.b}[0], [RGB], #3
-      ld3           {v10.b, v11.b, v12.b}[1], [RGB], #3
-      ld3           {v10.b, v11.b, v12.b}[2], [RGB], #3
-      ld3           {v10.b, v11.b, v12.b}[3], [RGB], #3
-    .elseif \size == 2
-      ld3           {v10.b, v11.b, v12.b}[4], [RGB], #3
-      ld3           {v10.b, v11.b, v12.b}[5], [RGB], #3
-    .elseif \size == 1
-      ld3           {v10.b, v11.b, v12.b}[6], [RGB], #3
-    .else
-      .error unsupported macroblock size
-    .endif
-  .elseif \bpp == 32
-    .if \size == 8
-      ld4           {v10.8b, v11.8b, v12.8b, v13.8b}, [RGB], #32
-      prfm          pldl1keep, [RGB, #128]
-    .elseif \size == 4
-      ld4           {v10.b, v11.b, v12.b, v13.b}[0], [RGB], #4
-      ld4           {v10.b, v11.b, v12.b, v13.b}[1], [RGB], #4
-      ld4           {v10.b, v11.b, v12.b, v13.b}[2], [RGB], #4
-      ld4           {v10.b, v11.b, v12.b, v13.b}[3], [RGB], #4
-    .elseif \size == 2
-      ld4           {v10.b, v11.b, v12.b, v13.b}[4], [RGB], #4
-      ld4           {v10.b, v11.b, v12.b, v13.b}[5], [RGB], #4
-    .elseif \size == 1
-      ld4           {v10.b, v11.b, v12.b, v13.b}[6], [RGB], #4
-    .else
-      .error unsupported macroblock size
-    .endif
-  .else
-    .error unsupported bpp
-  .endif
-.endm
-
-.macro generate_jsimd_rgb_ycc_convert_neon colorid, bpp, r_offs, g_offs, \
-                                           b_offs, fast_ld3
-
-/*
- * 2-stage pipelined RGB->YCbCr conversion
- */
-
-.macro do_rgb_to_yuv_stage1
-    ushll           v4.8h, v1\r_offs\().8b, #0  /* r = v4 */
-    ushll           v6.8h, v1\g_offs\().8b, #0  /* g = v6 */
-    ushll           v8.8h, v1\b_offs\().8b, #0  /* b = v8 */
-    rev64           v18.4s, v1.4s
-    rev64           v26.4s, v1.4s
-    rev64           v28.4s, v1.4s
-    rev64           v30.4s, v1.4s
-    umull           v14.4s, v4.4h, v0.h[0]
-    umull2          v16.4s, v4.8h, v0.h[0]
-    umlsl           v18.4s, v4.4h, v0.h[3]
-    umlsl2          v26.4s, v4.8h, v0.h[3]
-    umlal           v28.4s, v4.4h, v0.h[5]
-    umlal2          v30.4s, v4.8h, v0.h[5]
-    umlal           v14.4s, v6.4h, v0.h[1]
-    umlal2          v16.4s, v6.8h, v0.h[1]
-    umlsl           v18.4s, v6.4h, v0.h[4]
-    umlsl2          v26.4s, v6.8h, v0.h[4]
-    umlsl           v28.4s, v6.4h, v0.h[6]
-    umlsl2          v30.4s, v6.8h, v0.h[6]
-    umlal           v14.4s, v8.4h, v0.h[2]
-    umlal2          v16.4s, v8.8h, v0.h[2]
-    umlal           v18.4s, v8.4h, v0.h[5]
-    umlal2          v26.4s, v8.8h, v0.h[5]
-    umlsl           v28.4s, v8.4h, v0.h[7]
-    umlsl2          v30.4s, v8.8h, v0.h[7]
-.endm
-
-.macro do_rgb_to_yuv_stage2
-    rshrn           v20.4h, v14.4s, #16
-    shrn            v22.4h, v18.4s, #16
-    shrn            v24.4h, v28.4s, #16
-    rshrn2          v20.8h, v16.4s, #16
-    shrn2           v22.8h, v26.4s, #16
-    shrn2           v24.8h, v30.4s, #16
-    xtn             v20.8b, v20.8h       /* v20 = y */
-    xtn             v21.8b, v22.8h       /* v21 = u */
-    xtn             v22.8b, v24.8h       /* v22 = v */
-.endm
-
-.macro do_rgb_to_yuv
-    do_rgb_to_yuv_stage1
-    do_rgb_to_yuv_stage2
-.endm
-
-/* TODO: expand macros and interleave instructions if some in-order
- *       ARM64 processor actually can dual-issue LOAD/STORE with ALU */
-.macro do_rgb_to_yuv_stage2_store_load_stage1 fast_ld3
-    do_rgb_to_yuv_stage2
-    do_load         \bpp, 8, \fast_ld3
-    st1             {v20.8b}, [Y], #8
-    st1             {v21.8b}, [U], #8
-    st1             {v22.8b}, [V], #8
-    do_rgb_to_yuv_stage1
-.endm
-
-.balign 16
-.if \fast_ld3 == 1
-Ljsimd_\colorid\()_ycc_neon_consts:
-.else
-Ljsimd_\colorid\()_ycc_neon_slowld3_consts:
-.endif
-  .short 19595, 38470, 7471, 11059
-  .short 21709, 32768, 27439, 5329
-  .short 32767, 128, 32767, 128
-  .short 32767, 128, 32767, 128
-
-.if \fast_ld3 == 1
-asm_function jsimd_\colorid\()_ycc_convert_neon
-.else
-asm_function jsimd_\colorid\()_ycc_convert_neon_slowld3
-.endif
-    OUTPUT_WIDTH    .req w0
-    INPUT_BUF       .req x1
-    OUTPUT_BUF      .req x2
-    OUTPUT_ROW      .req w3
-    NUM_ROWS        .req w4
-
-    OUTPUT_BUF0     .req x5
-    OUTPUT_BUF1     .req x6
-    OUTPUT_BUF2     .req x2  /* OUTPUT_BUF */
-
-    RGB             .req x7
-    Y               .req x9
-    U               .req x10
-    V               .req x11
-    N               .req w12
-
-    /* Load constants to d0, d1, d2, d3 */
-    .if \fast_ld3 == 1
-      adr           x13, Ljsimd_\colorid\()_ycc_neon_consts
-    .else
-      adr           x13, Ljsimd_\colorid\()_ycc_neon_slowld3_consts
-    .endif
-    ld1             {v0.8h, v1.8h}, [x13]
-
-    ldr             OUTPUT_BUF0, [OUTPUT_BUF]
-    ldr             OUTPUT_BUF1, [OUTPUT_BUF, #8]
-    ldr             OUTPUT_BUF2, [OUTPUT_BUF, #16]
-    .unreq          OUTPUT_BUF
-
-    /* Save NEON registers */
-    sub             sp, sp, #64
-    mov             x9, sp
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
-
-    /* Outer loop over scanlines */
-    cmp             NUM_ROWS, #1
-    b.lt            9f
-0:
-    ldr             Y, [OUTPUT_BUF0, OUTPUT_ROW, uxtw #3]
-    ldr             U, [OUTPUT_BUF1, OUTPUT_ROW, uxtw #3]
-    mov             N, OUTPUT_WIDTH
-    ldr             V, [OUTPUT_BUF2, OUTPUT_ROW, uxtw #3]
-    add             OUTPUT_ROW, OUTPUT_ROW, #1
-    ldr             RGB, [INPUT_BUF], #8
-
-    /* Inner loop over pixels */
-    subs            N, N, #8
-    b.lt            3f
-    do_load         \bpp, 8, \fast_ld3
-    do_rgb_to_yuv_stage1
-    subs            N, N, #8
-    b.lt            2f
-1:
-    do_rgb_to_yuv_stage2_store_load_stage1 \fast_ld3
-    subs            N, N, #8
-    b.ge            1b
-2:
-    do_rgb_to_yuv_stage2
-    do_store        8
-    tst             N, #7
-    b.eq            8f
-3:
-    tbz             N, #2, 3f
-    do_load         \bpp, 4, \fast_ld3
-3:
-    tbz             N, #1, 4f
-    do_load         \bpp, 2, \fast_ld3
-4:
-    tbz             N, #0, 5f
-    do_load         \bpp, 1, \fast_ld3
-5:
-    do_rgb_to_yuv
-    tbz             N, #2, 6f
-    do_store        4
-6:
-    tbz             N, #1, 7f
-    do_store        2
-7:
-    tbz             N, #0, 8f
-    do_store        1
-8:
-    subs            NUM_ROWS, NUM_ROWS, #1
-    b.gt            0b
-9:
-    /* Restore all registers and return */
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
-    br              x30
-
-    .unreq          OUTPUT_WIDTH
-    .unreq          OUTPUT_ROW
-    .unreq          INPUT_BUF
-    .unreq          NUM_ROWS
-    .unreq          OUTPUT_BUF0
-    .unreq          OUTPUT_BUF1
-    .unreq          OUTPUT_BUF2
-    .unreq          RGB
-    .unreq          Y
-    .unreq          U
-    .unreq          V
-    .unreq          N
-
-.purgem do_rgb_to_yuv
-.purgem do_rgb_to_yuv_stage1
-.purgem do_rgb_to_yuv_stage2
-.purgem do_rgb_to_yuv_stage2_store_load_stage1
-
-.endm
-
-/*--------------------------------- id ----- bpp R  G  B  Fast LD3 */
-generate_jsimd_rgb_ycc_convert_neon extrgb,  24, 0, 1, 2, 1
-generate_jsimd_rgb_ycc_convert_neon extbgr,  24, 2, 1, 0, 1
-generate_jsimd_rgb_ycc_convert_neon extrgbx, 32, 0, 1, 2, 1
-generate_jsimd_rgb_ycc_convert_neon extbgrx, 32, 2, 1, 0, 1
-generate_jsimd_rgb_ycc_convert_neon extxbgr, 32, 3, 2, 1, 1
-generate_jsimd_rgb_ycc_convert_neon extxrgb, 32, 1, 2, 3, 1
-
-generate_jsimd_rgb_ycc_convert_neon extrgb,  24, 0, 1, 2, 0
-generate_jsimd_rgb_ycc_convert_neon extbgr,  24, 2, 1, 0, 0
-
-.purgem do_load
-.purgem do_store
-
-
-/*****************************************************************************/
-
-/*
- * Load data into workspace, applying unsigned->signed conversion
- *
- * TODO: can be combined with 'jsimd_fdct_ifast_neon' to get
- *       rid of VST1.16 instructions
- */
-
-asm_function jsimd_convsamp_neon
-    SAMPLE_DATA     .req x0
-    START_COL       .req x1
-    WORKSPACE       .req x2
-    TMP1            .req x9
-    TMP2            .req x10
-    TMP3            .req x11
-    TMP4            .req x12
-    TMP5            .req x13
-    TMP6            .req x14
-    TMP7            .req x15
-    TMP8            .req x4
-    TMPDUP          .req w3
-
-    /* START_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
-       guarantee that the upper (unused) 32 bits of x1 are valid.  This
-       instruction ensures that those bits are set to zero. */
-    uxtw x1, w1
-
-    mov             TMPDUP, #128
-    ldp             TMP1, TMP2, [SAMPLE_DATA], 16
-    ldp             TMP3, TMP4, [SAMPLE_DATA], 16
-    dup             v0.8b, TMPDUP
-    add             TMP1, TMP1, START_COL
-    add             TMP2, TMP2, START_COL
-    ldp             TMP5, TMP6, [SAMPLE_DATA], 16
-    add             TMP3, TMP3, START_COL
-    add             TMP4, TMP4, START_COL
-    ldp             TMP7, TMP8, [SAMPLE_DATA], 16
-    add             TMP5, TMP5, START_COL
-    add             TMP6, TMP6, START_COL
-    ld1             {v16.8b}, [TMP1]
-    add             TMP7, TMP7, START_COL
-    add             TMP8, TMP8, START_COL
-    ld1             {v17.8b}, [TMP2]
-    usubl           v16.8h, v16.8b, v0.8b
-    ld1             {v18.8b}, [TMP3]
-    usubl           v17.8h, v17.8b, v0.8b
-    ld1             {v19.8b}, [TMP4]
-    usubl           v18.8h, v18.8b, v0.8b
-    ld1             {v20.8b}, [TMP5]
-    usubl           v19.8h, v19.8b, v0.8b
-    ld1             {v21.8b}, [TMP6]
-    st1             {v16.8h, v17.8h, v18.8h, v19.8h}, [WORKSPACE], 64
-    usubl           v20.8h, v20.8b, v0.8b
-    ld1             {v22.8b}, [TMP7]
-    usubl           v21.8h, v21.8b, v0.8b
-    ld1             {v23.8b}, [TMP8]
-    usubl           v22.8h, v22.8b, v0.8b
-    usubl           v23.8h, v23.8b, v0.8b
-    st1             {v20.8h, v21.8h, v22.8h, v23.8h}, [WORKSPACE], 64
-
-    br              x30
-
-    .unreq          SAMPLE_DATA
-    .unreq          START_COL
-    .unreq          WORKSPACE
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMP4
-    .unreq          TMP5
-    .unreq          TMP6
-    .unreq          TMP7
-    .unreq          TMP8
-    .unreq          TMPDUP
-
-/*****************************************************************************/
-
-/*
- * jsimd_fdct_islow_neon
- *
- * This file contains a slow-but-accurate integer implementation of the
- * forward DCT (Discrete Cosine Transform). The following code is based
- * directly on the IJG''s original jfdctint.c; see the jfdctint.c for
- * more details.
- *
- * TODO: can be combined with 'jsimd_convsamp_neon' to get
- *       rid of a bunch of VLD1.16 instructions
- */
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-
-#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
-#define DESCALE_P2  (CONST_BITS + PASS1_BITS)
-
-#define F_0_298   2446  /* FIX(0.298631336) */
-#define F_0_390   3196  /* FIX(0.390180644) */
-#define F_0_541   4433  /* FIX(0.541196100) */
-#define F_0_765   6270  /* FIX(0.765366865) */
-#define F_0_899   7373  /* FIX(0.899976223) */
-#define F_1_175   9633  /* FIX(1.175875602) */
-#define F_1_501  12299  /* FIX(1.501321110) */
-#define F_1_847  15137  /* FIX(1.847759065) */
-#define F_1_961  16069  /* FIX(1.961570560) */
-#define F_2_053  16819  /* FIX(2.053119869) */
-#define F_2_562  20995  /* FIX(2.562915447) */
-#define F_3_072  25172  /* FIX(3.072711026) */
-
-.balign 16
-Ljsimd_fdct_islow_neon_consts:
-  .short F_0_298
-  .short -F_0_390
-  .short F_0_541
-  .short F_0_765
-  .short - F_0_899
-  .short F_1_175
-  .short F_1_501
-  .short - F_1_847
-  .short - F_1_961
-  .short F_2_053
-  .short - F_2_562
-  .short F_3_072
-  .short 0          /* padding */
-  .short 0
-  .short 0
-  .short 0
-
-#undef F_0_298
-#undef F_0_390
-#undef F_0_541
-#undef F_0_765
-#undef F_0_899
-#undef F_1_175
-#undef F_1_501
-#undef F_1_847
-#undef F_1_961
-#undef F_2_053
-#undef F_2_562
-#undef F_3_072
-#define XFIX_P_0_298  v0.h[0]
-#define XFIX_N_0_390  v0.h[1]
-#define XFIX_P_0_541  v0.h[2]
-#define XFIX_P_0_765  v0.h[3]
-#define XFIX_N_0_899  v0.h[4]
-#define XFIX_P_1_175  v0.h[5]
-#define XFIX_P_1_501  v0.h[6]
-#define XFIX_N_1_847  v0.h[7]
-#define XFIX_N_1_961  v1.h[0]
-#define XFIX_P_2_053  v1.h[1]
-#define XFIX_N_2_562  v1.h[2]
-#define XFIX_P_3_072  v1.h[3]
-
-asm_function jsimd_fdct_islow_neon
-
-    DATA            .req x0
-    TMP             .req x9
-
-    /* Load constants */
-    adr             TMP, Ljsimd_fdct_islow_neon_consts
-    ld1             {v0.8h, v1.8h}, [TMP]
-
-    /* Save NEON registers */
-    sub             sp, sp, #64
-    mov             x10, sp
-    st1             {v8.8b, v9.8b, v10.8b, v11.8b}, [x10], 32
-    st1             {v12.8b, v13.8b, v14.8b, v15.8b}, [x10], 32
-
-    /* Load all DATA into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17    | v16.8h
-     *   1 | d18     | d19    | v17.8h
-     *   2 | d20     | d21    | v18.8h
-     *   3 | d22     | d23    | v19.8h
-     *   4 | d24     | d25    | v20.8h
-     *   5 | d26     | d27    | v21.8h
-     *   6 | d28     | d29    | v22.8h
-     *   7 | d30     | d31    | v23.8h
-     */
-
-    ld1             {v16.8h, v17.8h, v18.8h, v19.8h}, [DATA], 64
-    ld1             {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA]
-    sub             DATA, DATA, #64
-
-    /* Transpose */
-    transpose_8x8   v16, v17, v18, v19, v20, v21, v22, v23, v31, v2, v3, v4
-    /* 1-D FDCT */
-    add             v24.8h, v16.8h, v23.8h  /* tmp0 = dataptr[0] + dataptr[7]; */
-    sub             v31.8h, v16.8h, v23.8h  /* tmp7 = dataptr[0] - dataptr[7]; */
-    add             v25.8h, v17.8h, v22.8h  /* tmp1 = dataptr[1] + dataptr[6]; */
-    sub             v30.8h, v17.8h, v22.8h  /* tmp6 = dataptr[1] - dataptr[6]; */
-    add             v26.8h, v18.8h, v21.8h  /* tmp2 = dataptr[2] + dataptr[5]; */
-    sub             v29.8h, v18.8h, v21.8h  /* tmp5 = dataptr[2] - dataptr[5]; */
-    add             v27.8h, v19.8h, v20.8h  /* tmp3 = dataptr[3] + dataptr[4]; */
-    sub             v28.8h, v19.8h, v20.8h  /* tmp4 = dataptr[3] - dataptr[4]; */
-
-    /* even part */
-
-    add             v8.8h, v24.8h, v27.8h   /* tmp10 = tmp0 + tmp3; */
-    sub             v9.8h, v24.8h, v27.8h   /* tmp13 = tmp0 - tmp3; */
-    add             v10.8h, v25.8h, v26.8h  /* tmp11 = tmp1 + tmp2; */
-    sub             v11.8h, v25.8h, v26.8h  /* tmp12 = tmp1 - tmp2; */
-
-    add             v16.8h, v8.8h, v10.8h  /* tmp10 + tmp11 */
-    sub             v20.8h, v8.8h, v10.8h  /* tmp10 - tmp11 */
-
-    add             v18.8h, v11.8h, v9.8h  /* tmp12 + tmp13 */
-
-    shl             v16.8h, v16.8h, #PASS1_BITS  /* dataptr[0] = (DCTELEM)LEFT_SHIFT(tmp10 + tmp11, PASS1_BITS); */
-    shl             v20.8h, v20.8h, #PASS1_BITS  /* dataptr[4] = (DCTELEM)LEFT_SHIFT(tmp10 - tmp11, PASS1_BITS); */
-
-    smull2          v24.4s, v18.8h, XFIX_P_0_541  /* z1 hi = MULTIPLY(tmp12 + tmp13, XFIX_P_0_541); */
-    smull           v18.4s, v18.4h, XFIX_P_0_541  /* z1 lo = MULTIPLY(tmp12 + tmp13, XFIX_P_0_541); */
-    mov             v22.16b, v18.16b
-    mov             v25.16b, v24.16b
-
-    smlal           v18.4s, v9.4h, XFIX_P_0_765   /* lo z1 + MULTIPLY(tmp13, XFIX_P_0_765) */
-    smlal2          v24.4s, v9.8h, XFIX_P_0_765   /* hi z1 + MULTIPLY(tmp13, XFIX_P_0_765) */
-    smlal           v22.4s, v11.4h, XFIX_N_1_847  /* lo z1 + MULTIPLY(tmp12, XFIX_N_1_847) */
-    smlal2          v25.4s, v11.8h, XFIX_N_1_847  /* hi z1 + MULTIPLY(tmp12, XFIX_N_1_847) */
-
-    rshrn           v18.4h, v18.4s, #DESCALE_P1
-    rshrn           v22.4h, v22.4s, #DESCALE_P1
-    rshrn2          v18.8h, v24.4s, #DESCALE_P1  /* dataptr[2] = (DCTELEM)DESCALE(z1 + MULTIPLY(tmp13, XFIX_P_0_765), CONST_BITS-PASS1_BITS); */
-    rshrn2          v22.8h, v25.4s, #DESCALE_P1  /* dataptr[6] = (DCTELEM)DESCALE(z1 + MULTIPLY(tmp12, XFIX_N_1_847), CONST_BITS-PASS1_BITS); */
-
-    /* Odd part */
-
-    add             v8.8h, v28.8h, v31.8h        /* z1 = tmp4 + tmp7; */
-    add             v9.8h, v29.8h, v30.8h        /* z2 = tmp5 + tmp6; */
-    add             v10.8h, v28.8h, v30.8h       /* z3 = tmp4 + tmp6; */
-    add             v11.8h, v29.8h, v31.8h       /* z4 = tmp5 + tmp7; */
-    smull           v4.4s, v10.4h, XFIX_P_1_175  /* z5 lo = z3 lo * XFIX_P_1_175 */
-    smull2          v5.4s, v10.8h, XFIX_P_1_175
-    smlal           v4.4s, v11.4h, XFIX_P_1_175  /* z5 = MULTIPLY(z3 + z4, FIX_1_175875602); */
-    smlal2          v5.4s, v11.8h, XFIX_P_1_175
-
-    smull2          v24.4s, v28.8h, XFIX_P_0_298
-    smull2          v25.4s, v29.8h, XFIX_P_2_053
-    smull2          v26.4s, v30.8h, XFIX_P_3_072
-    smull2          v27.4s, v31.8h, XFIX_P_1_501
-    smull           v28.4s, v28.4h, XFIX_P_0_298  /* tmp4 = MULTIPLY(tmp4, FIX_0_298631336); */
-    smull           v29.4s, v29.4h, XFIX_P_2_053  /* tmp5 = MULTIPLY(tmp5, FIX_2_053119869); */
-    smull           v30.4s, v30.4h, XFIX_P_3_072  /* tmp6 = MULTIPLY(tmp6, FIX_3_072711026); */
-    smull           v31.4s, v31.4h, XFIX_P_1_501  /* tmp7 = MULTIPLY(tmp7, FIX_1_501321110); */
-
-    smull2          v12.4s, v8.8h, XFIX_N_0_899
-    smull2          v13.4s, v9.8h, XFIX_N_2_562
-    smull2          v14.4s, v10.8h, XFIX_N_1_961
-    smull2          v15.4s, v11.8h, XFIX_N_0_390
-    smull           v8.4s, v8.4h, XFIX_N_0_899    /* z1 = MULTIPLY(z1, -FIX_0_899976223); */
-    smull           v9.4s, v9.4h, XFIX_N_2_562    /* z2 = MULTIPLY(z2, -FIX_2_562915447); */
-    smull           v10.4s, v10.4h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560); */
-    smull           v11.4s, v11.4h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644); */
-
-    add             v10.4s, v10.4s, v4.4s  /* z3 += z5 */
-    add             v14.4s, v14.4s, v5.4s
-    add             v11.4s, v11.4s, v4.4s  /* z4 += z5 */
-    add             v15.4s, v15.4s, v5.4s
-
-    add             v28.4s, v28.4s, v8.4s   /* tmp4 += z1 */
-    add             v24.4s, v24.4s, v12.4s
-    add             v29.4s, v29.4s, v9.4s   /* tmp5 += z2 */
-    add             v25.4s, v25.4s, v13.4s
-    add             v30.4s, v30.4s, v10.4s  /* tmp6 += z3 */
-    add             v26.4s, v26.4s, v14.4s
-    add             v31.4s, v31.4s, v11.4s  /* tmp7 += z4 */
-    add             v27.4s, v27.4s, v15.4s
-
-    add             v28.4s, v28.4s, v10.4s  /* tmp4 += z3 */
-    add             v24.4s, v24.4s, v14.4s
-    add             v29.4s, v29.4s, v11.4s  /* tmp5 += z4 */
-    add             v25.4s, v25.4s, v15.4s
-    add             v30.4s, v30.4s, v9.4s   /* tmp6 += z2 */
-    add             v26.4s, v26.4s, v13.4s
-    add             v31.4s, v31.4s, v8.4s   /* tmp7 += z1 */
-    add             v27.4s, v27.4s, v12.4s
-
-    rshrn           v23.4h, v28.4s, #DESCALE_P1
-    rshrn           v21.4h, v29.4s, #DESCALE_P1
-    rshrn           v19.4h, v30.4s, #DESCALE_P1
-    rshrn           v17.4h, v31.4s, #DESCALE_P1
-    rshrn2          v23.8h, v24.4s, #DESCALE_P1  /* dataptr[7] = (DCTELEM)DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); */
-    rshrn2          v21.8h, v25.4s, #DESCALE_P1  /* dataptr[5] = (DCTELEM)DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); */
-    rshrn2          v19.8h, v26.4s, #DESCALE_P1  /* dataptr[3] = (DCTELEM)DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); */
-    rshrn2          v17.8h, v27.4s, #DESCALE_P1  /* dataptr[1] = (DCTELEM)DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); */
-
-    /* Transpose */
-    transpose_8x8   v16, v17, v18, v19, v20, v21, v22, v23, v31, v2, v3, v4
-
-    /* 1-D FDCT */
-    add             v24.8h, v16.8h, v23.8h  /* tmp0 = dataptr[0] + dataptr[7]; */
-    sub             v31.8h, v16.8h, v23.8h  /* tmp7 = dataptr[0] - dataptr[7]; */
-    add             v25.8h, v17.8h, v22.8h  /* tmp1 = dataptr[1] + dataptr[6]; */
-    sub             v30.8h, v17.8h, v22.8h  /* tmp6 = dataptr[1] - dataptr[6]; */
-    add             v26.8h, v18.8h, v21.8h  /* tmp2 = dataptr[2] + dataptr[5]; */
-    sub             v29.8h, v18.8h, v21.8h  /* tmp5 = dataptr[2] - dataptr[5]; */
-    add             v27.8h, v19.8h, v20.8h  /* tmp3 = dataptr[3] + dataptr[4]; */
-    sub             v28.8h, v19.8h, v20.8h  /* tmp4 = dataptr[3] - dataptr[4]; */
-
-    /* even part */
-    add             v8.8h, v24.8h, v27.8h   /* tmp10 = tmp0 + tmp3; */
-    sub             v9.8h, v24.8h, v27.8h   /* tmp13 = tmp0 - tmp3; */
-    add             v10.8h, v25.8h, v26.8h  /* tmp11 = tmp1 + tmp2; */
-    sub             v11.8h, v25.8h, v26.8h  /* tmp12 = tmp1 - tmp2; */
-
-    add             v16.8h, v8.8h, v10.8h  /* tmp10 + tmp11 */
-    sub             v20.8h, v8.8h, v10.8h  /* tmp10 - tmp11 */
-
-    add             v18.8h, v11.8h, v9.8h  /* tmp12 + tmp13 */
-
-    srshr           v16.8h, v16.8h, #PASS1_BITS  /* dataptr[0] = (DCTELEM)DESCALE(tmp10 + tmp11, PASS1_BITS); */
-    srshr           v20.8h, v20.8h, #PASS1_BITS  /* dataptr[4] = (DCTELEM)DESCALE(tmp10 - tmp11, PASS1_BITS); */
-
-    smull2          v24.4s, v18.8h, XFIX_P_0_541  /* z1 hi = MULTIPLY(tmp12 + tmp13, XFIX_P_0_541); */
-    smull           v18.4s, v18.4h, XFIX_P_0_541  /* z1 lo = MULTIPLY(tmp12 + tmp13, XFIX_P_0_541); */
-    mov             v22.16b, v18.16b
-    mov             v25.16b, v24.16b
-
-    smlal           v18.4s, v9.4h, XFIX_P_0_765   /* lo z1 + MULTIPLY(tmp13, XFIX_P_0_765) */
-    smlal2          v24.4s, v9.8h, XFIX_P_0_765   /* hi z1 + MULTIPLY(tmp13, XFIX_P_0_765) */
-    smlal           v22.4s, v11.4h, XFIX_N_1_847  /* lo z1 + MULTIPLY(tmp12, XFIX_N_1_847) */
-    smlal2          v25.4s, v11.8h, XFIX_N_1_847  /* hi z1 + MULTIPLY(tmp12, XFIX_N_1_847) */
-
-    rshrn           v18.4h, v18.4s, #DESCALE_P2
-    rshrn           v22.4h, v22.4s, #DESCALE_P2
-    rshrn2          v18.8h, v24.4s, #DESCALE_P2  /* dataptr[2] = (DCTELEM)DESCALE(z1 + MULTIPLY(tmp13, XFIX_P_0_765), CONST_BITS-PASS1_BITS); */
-    rshrn2          v22.8h, v25.4s, #DESCALE_P2  /* dataptr[6] = (DCTELEM)DESCALE(z1 + MULTIPLY(tmp12, XFIX_N_1_847), CONST_BITS-PASS1_BITS); */
-
-    /* Odd part */
-    add             v8.8h, v28.8h, v31.8h   /* z1 = tmp4 + tmp7; */
-    add             v9.8h, v29.8h, v30.8h   /* z2 = tmp5 + tmp6; */
-    add             v10.8h, v28.8h, v30.8h  /* z3 = tmp4 + tmp6; */
-    add             v11.8h, v29.8h, v31.8h  /* z4 = tmp5 + tmp7; */
-
-    smull           v4.4s, v10.4h, XFIX_P_1_175  /* z5 lo = z3 lo * XFIX_P_1_175 */
-    smull2          v5.4s, v10.8h, XFIX_P_1_175
-    smlal           v4.4s, v11.4h, XFIX_P_1_175  /* z5 = MULTIPLY(z3 + z4, FIX_1_175875602); */
-    smlal2          v5.4s, v11.8h, XFIX_P_1_175
-
-    smull2          v24.4s, v28.8h, XFIX_P_0_298
-    smull2          v25.4s, v29.8h, XFIX_P_2_053
-    smull2          v26.4s, v30.8h, XFIX_P_3_072
-    smull2          v27.4s, v31.8h, XFIX_P_1_501
-    smull           v28.4s, v28.4h, XFIX_P_0_298  /* tmp4 = MULTIPLY(tmp4, FIX_0_298631336); */
-    smull           v29.4s, v29.4h, XFIX_P_2_053  /* tmp5 = MULTIPLY(tmp5, FIX_2_053119869); */
-    smull           v30.4s, v30.4h, XFIX_P_3_072  /* tmp6 = MULTIPLY(tmp6, FIX_3_072711026); */
-    smull           v31.4s, v31.4h, XFIX_P_1_501  /* tmp7 = MULTIPLY(tmp7, FIX_1_501321110); */
-
-    smull2          v12.4s, v8.8h, XFIX_N_0_899
-    smull2          v13.4s, v9.8h, XFIX_N_2_562
-    smull2          v14.4s, v10.8h, XFIX_N_1_961
-    smull2          v15.4s, v11.8h, XFIX_N_0_390
-    smull           v8.4s, v8.4h, XFIX_N_0_899    /* z1 = MULTIPLY(z1, -FIX_0_899976223); */
-    smull           v9.4s, v9.4h, XFIX_N_2_562    /* z2 = MULTIPLY(z2, -FIX_2_562915447); */
-    smull           v10.4s, v10.4h, XFIX_N_1_961  /* z3 = MULTIPLY(z3, -FIX_1_961570560); */
-    smull           v11.4s, v11.4h, XFIX_N_0_390  /* z4 = MULTIPLY(z4, -FIX_0_390180644); */
-
-    add             v10.4s, v10.4s, v4.4s
-    add             v14.4s, v14.4s, v5.4s
-    add             v11.4s, v11.4s, v4.4s
-    add             v15.4s, v15.4s, v5.4s
-
-    add             v28.4s, v28.4s, v8.4s   /* tmp4 += z1 */
-    add             v24.4s, v24.4s, v12.4s
-    add             v29.4s, v29.4s, v9.4s   /* tmp5 += z2 */
-    add             v25.4s, v25.4s, v13.4s
-    add             v30.4s, v30.4s, v10.4s  /* tmp6 += z3 */
-    add             v26.4s, v26.4s, v14.4s
-    add             v31.4s, v31.4s, v11.4s  /* tmp7 += z4 */
-    add             v27.4s, v27.4s, v15.4s
-
-    add             v28.4s, v28.4s, v10.4s  /* tmp4 += z3 */
-    add             v24.4s, v24.4s, v14.4s
-    add             v29.4s, v29.4s, v11.4s  /* tmp5 += z4 */
-    add             v25.4s, v25.4s, v15.4s
-    add             v30.4s, v30.4s, v9.4s   /* tmp6 += z2 */
-    add             v26.4s, v26.4s, v13.4s
-    add             v31.4s, v31.4s, v8.4s   /* tmp7 += z1 */
-    add             v27.4s, v27.4s, v12.4s
-
-    rshrn           v23.4h, v28.4s, #DESCALE_P2
-    rshrn           v21.4h, v29.4s, #DESCALE_P2
-    rshrn           v19.4h, v30.4s, #DESCALE_P2
-    rshrn           v17.4h, v31.4s, #DESCALE_P2
-    rshrn2          v23.8h, v24.4s, #DESCALE_P2  /* dataptr[7] = (DCTELEM)DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); */
-    rshrn2          v21.8h, v25.4s, #DESCALE_P2  /* dataptr[5] = (DCTELEM)DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); */
-    rshrn2          v19.8h, v26.4s, #DESCALE_P2  /* dataptr[3] = (DCTELEM)DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); */
-    rshrn2          v17.8h, v27.4s, #DESCALE_P2  /* dataptr[1] = (DCTELEM)DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); */
-
-    /* store results */
-    st1             {v16.8h, v17.8h, v18.8h, v19.8h}, [DATA], 64
-    st1             {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA]
-
-    /* Restore NEON registers */
-    ld1             {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
-    ld1             {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
-
-    br              x30
-
-    .unreq          DATA
-    .unreq          TMP
-
-#undef XFIX_P_0_298
-#undef XFIX_N_0_390
-#undef XFIX_P_0_541
-#undef XFIX_P_0_765
-#undef XFIX_N_0_899
-#undef XFIX_P_1_175
-#undef XFIX_P_1_501
-#undef XFIX_N_1_847
-#undef XFIX_N_1_961
-#undef XFIX_P_2_053
-#undef XFIX_N_2_562
-#undef XFIX_P_3_072
-
-
-/*****************************************************************************/
-
-/*
- * jsimd_fdct_ifast_neon
- *
- * This function contains a fast, not so accurate integer implementation of
- * the forward DCT (Discrete Cosine Transform). It uses the same calculations
- * and produces exactly the same output as IJG's original 'jpeg_fdct_ifast'
- * function from jfdctfst.c
- *
- * TODO: can be combined with 'jsimd_convsamp_neon' to get
- *       rid of a bunch of VLD1.16 instructions
- */
-
-#undef XFIX_0_541196100
-#define XFIX_0_382683433  v0.h[0]
-#define XFIX_0_541196100  v0.h[1]
-#define XFIX_0_707106781  v0.h[2]
-#define XFIX_1_306562965  v0.h[3]
-
-.balign 16
-Ljsimd_fdct_ifast_neon_consts:
-  .short (98 * 128)               /* XFIX_0_382683433 */
-  .short (139 * 128)              /* XFIX_0_541196100 */
-  .short (181 * 128)              /* XFIX_0_707106781 */
-  .short (334 * 128 - 256 * 128)  /* XFIX_1_306562965 */
-
-asm_function jsimd_fdct_ifast_neon
-
-    DATA            .req x0
-    TMP             .req x9
-
-    /* Load constants */
-    adr             TMP, Ljsimd_fdct_ifast_neon_consts
-    ld1             {v0.4h}, [TMP]
-
-    /* Load all DATA into NEON registers with the following allocation:
-     *       0 1 2 3 | 4 5 6 7
-     *      ---------+--------
-     *   0 | d16     | d17    | v0.8h
-     *   1 | d18     | d19    | q9
-     *   2 | d20     | d21    | q10
-     *   3 | d22     | d23    | q11
-     *   4 | d24     | d25    | q12
-     *   5 | d26     | d27    | q13
-     *   6 | d28     | d29    | q14
-     *   7 | d30     | d31    | q15
-     */
-
-    ld1             {v16.8h, v17.8h, v18.8h, v19.8h}, [DATA], 64
-    ld1             {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA]
-    mov             TMP, #2
-    sub             DATA, DATA, #64
-1:
-    /* Transpose */
-    transpose_8x8   v16, v17, v18, v19, v20, v21, v22, v23, v1, v2, v3, v4
-    subs            TMP, TMP, #1
-    /* 1-D FDCT */
-    add             v4.8h, v19.8h, v20.8h
-    sub             v20.8h, v19.8h, v20.8h
-    sub             v28.8h, v18.8h, v21.8h
-    add             v18.8h, v18.8h, v21.8h
-    sub             v29.8h, v17.8h, v22.8h
-    add             v17.8h, v17.8h, v22.8h
-    sub             v21.8h, v16.8h, v23.8h
-    add             v16.8h, v16.8h, v23.8h
-    sub             v6.8h, v17.8h, v18.8h
-    sub             v7.8h, v16.8h, v4.8h
-    add             v5.8h, v17.8h, v18.8h
-    add             v6.8h, v6.8h, v7.8h
-    add             v4.8h, v16.8h, v4.8h
-    sqdmulh         v6.8h, v6.8h, XFIX_0_707106781
-    add             v19.8h, v20.8h, v28.8h
-    add             v16.8h, v4.8h, v5.8h
-    sub             v20.8h, v4.8h, v5.8h
-    add             v5.8h, v28.8h, v29.8h
-    add             v29.8h, v29.8h, v21.8h
-    sqdmulh         v5.8h, v5.8h, XFIX_0_707106781
-    sub             v28.8h, v19.8h, v29.8h
-    add             v18.8h, v7.8h, v6.8h
-    sqdmulh         v28.8h, v28.8h, XFIX_0_382683433
-    sub             v22.8h, v7.8h, v6.8h
-    sqdmulh         v19.8h, v19.8h, XFIX_0_541196100
-    sqdmulh         v7.8h, v29.8h, XFIX_1_306562965
-    add             v6.8h, v21.8h, v5.8h
-    sub             v5.8h, v21.8h, v5.8h
-    add             v29.8h, v29.8h, v28.8h
-    add             v19.8h, v19.8h, v28.8h
-    add             v29.8h, v29.8h, v7.8h
-    add             v21.8h, v5.8h, v19.8h
-    sub             v19.8h, v5.8h, v19.8h
-    add             v17.8h, v6.8h, v29.8h
-    sub             v23.8h, v6.8h, v29.8h
-
-    b.ne            1b
-
-    /* store results */
-    st1             {v16.8h, v17.8h, v18.8h, v19.8h}, [DATA], 64
-    st1             {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA]
-
-    br              x30
-
-    .unreq          DATA
-    .unreq          TMP
-#undef XFIX_0_382683433
-#undef XFIX_0_541196100
-#undef XFIX_0_707106781
-#undef XFIX_1_306562965
-
-
-/*****************************************************************************/
-
-/*
- * GLOBAL(void)
- * jsimd_quantize_neon(JCOEFPTR coef_block, DCTELEM *divisors,
- *                     DCTELEM *workspace);
- *
- */
-asm_function jsimd_quantize_neon
-
-    COEF_BLOCK      .req x0
-    DIVISORS        .req x1
-    WORKSPACE       .req x2
-
-    RECIPROCAL      .req DIVISORS
-    CORRECTION      .req x9
-    SHIFT           .req x10
-    LOOP_COUNT      .req x11
-
-    mov             LOOP_COUNT, #2
-    add             CORRECTION, DIVISORS, #(64 * 2)
-    add             SHIFT, DIVISORS, #(64 * 6)
-1:
-    subs            LOOP_COUNT, LOOP_COUNT, #1
-    ld1             {v0.8h, v1.8h, v2.8h, v3.8h}, [WORKSPACE], 64
-    ld1             {v4.8h, v5.8h, v6.8h, v7.8h}, [CORRECTION], 64
-    abs             v20.8h, v0.8h
-    abs             v21.8h, v1.8h
-    abs             v22.8h, v2.8h
-    abs             v23.8h, v3.8h
-    ld1             {v28.8h, v29.8h, v30.8h, v31.8h}, [RECIPROCAL], 64
-    add             v20.8h, v20.8h, v4.8h  /* add correction */
-    add             v21.8h, v21.8h, v5.8h
-    add             v22.8h, v22.8h, v6.8h
-    add             v23.8h, v23.8h, v7.8h
-    umull           v4.4s, v20.4h, v28.4h  /* multiply by reciprocal */
-    umull2          v16.4s, v20.8h, v28.8h
-    umull           v5.4s, v21.4h, v29.4h
-    umull2          v17.4s, v21.8h, v29.8h
-    umull           v6.4s, v22.4h, v30.4h  /* multiply by reciprocal */
-    umull2          v18.4s, v22.8h, v30.8h
-    umull           v7.4s, v23.4h, v31.4h
-    umull2          v19.4s, v23.8h, v31.8h
-    ld1             {v24.8h, v25.8h, v26.8h, v27.8h}, [SHIFT], 64
-    shrn            v4.4h, v4.4s, #16
-    shrn            v5.4h, v5.4s, #16
-    shrn            v6.4h, v6.4s, #16
-    shrn            v7.4h, v7.4s, #16
-    shrn2           v4.8h, v16.4s, #16
-    shrn2           v5.8h, v17.4s, #16
-    shrn2           v6.8h, v18.4s, #16
-    shrn2           v7.8h, v19.4s, #16
-    neg             v24.8h, v24.8h
-    neg             v25.8h, v25.8h
-    neg             v26.8h, v26.8h
-    neg             v27.8h, v27.8h
-    sshr            v0.8h, v0.8h, #15  /* extract sign */
-    sshr            v1.8h, v1.8h, #15
-    sshr            v2.8h, v2.8h, #15
-    sshr            v3.8h, v3.8h, #15
-    ushl            v4.8h, v4.8h, v24.8h  /* shift */
-    ushl            v5.8h, v5.8h, v25.8h
-    ushl            v6.8h, v6.8h, v26.8h
-    ushl            v7.8h, v7.8h, v27.8h
-
-    eor             v4.16b, v4.16b, v0.16b  /* restore sign */
-    eor             v5.16b, v5.16b, v1.16b
-    eor             v6.16b, v6.16b, v2.16b
-    eor             v7.16b, v7.16b, v3.16b
-    sub             v4.8h, v4.8h, v0.8h
-    sub             v5.8h, v5.8h, v1.8h
-    sub             v6.8h, v6.8h, v2.8h
-    sub             v7.8h, v7.8h, v3.8h
-    st1             {v4.8h, v5.8h, v6.8h, v7.8h}, [COEF_BLOCK], 64
-
-    b.ne            1b
-
-    br              x30  /* return */
-
-    .unreq          COEF_BLOCK
-    .unreq          DIVISORS
-    .unreq          WORKSPACE
-    .unreq          RECIPROCAL
-    .unreq          CORRECTION
-    .unreq          SHIFT
-    .unreq          LOOP_COUNT
-
-
-/*****************************************************************************/
-
-/*
- * Downsample pixel values of a single component.
- * This version handles the common case of 2:1 horizontal and 1:1 vertical,
- * without smoothing.
- *
- * GLOBAL(void)
- * jsimd_h2v1_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
- *                            JDIMENSION v_samp_factor,
- *                            JDIMENSION width_in_blocks,
- *                            JSAMPARRAY input_data, JSAMPARRAY output_data);
- */
-
-.balign 16
-Ljsimd_h2_downsample_neon_consts:
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F  /* diff 0 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0E  /* diff 1 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0D, 0x0D  /* diff 2 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0C, 0x0C, 0x0C  /* diff 3 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B  /* diff 4 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A  /* diff 5 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09  /* diff 6 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08  /* diff 7 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
-        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07  /* diff 8 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, \
-        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06  /* diff 9 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x05, \
-        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05  /* diff 10 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x04, 0x04, \
-        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04  /* diff 11 */
-  .byte 0x00, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, \
-        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03  /* diff 12 */
-  .byte 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, \
-        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02  /* diff 13 */
-  .byte 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, \
-        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01  /* diff 14 */
-  .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* diff 15 */
-
-asm_function jsimd_h2v1_downsample_neon
-    IMAGE_WIDTH     .req x0
-    MAX_V_SAMP      .req x1
-    V_SAMP          .req x2
-    BLOCK_WIDTH     .req x3
-    INPUT_DATA      .req x4
-    OUTPUT_DATA     .req x5
-    OUTPTR          .req x9
-    INPTR           .req x10
-    TMP1            .req x11
-    TMP2            .req x12
-    TMP3            .req x13
-    TMPDUP          .req w15
-
-    mov             TMPDUP, #0x10000
-    lsl             TMP2, BLOCK_WIDTH, #4
-    sub             TMP2, TMP2, IMAGE_WIDTH
-    adr             TMP3, Ljsimd_h2_downsample_neon_consts
-    add             TMP3, TMP3, TMP2, lsl #4
-    dup             v16.4s, TMPDUP
-    ld1             {v18.16b}, [TMP3]
-
-1:  /* row loop */
-    ldr             INPTR, [INPUT_DATA], #8
-    ldr             OUTPTR, [OUTPUT_DATA], #8
-    subs            TMP1, BLOCK_WIDTH, #1
-    b.eq            3f
-2:  /* columns */
-    ld1             {v0.16b}, [INPTR], #16
-    mov             v4.16b, v16.16b
-    subs            TMP1, TMP1, #1
-    uadalp          v4.8h, v0.16b
-    shrn            v6.8b, v4.8h, #1
-    st1             {v6.8b}, [OUTPTR], #8
-    b.ne            2b
-3:  /* last columns */
-    ld1             {v0.16b}, [INPTR]
-    mov             v4.16b, v16.16b
-    subs            V_SAMP, V_SAMP, #1
-    /* expand right */
-    tbl             v2.16b, {v0.16b}, v18.16b
-    uadalp          v4.8h, v2.16b
-    shrn            v6.8b, v4.8h, #1
-    st1             {v6.8b}, [OUTPTR], #8
-    b.ne            1b
-
-    br              x30
-
-    .unreq          IMAGE_WIDTH
-    .unreq          MAX_V_SAMP
-    .unreq          V_SAMP
-    .unreq          BLOCK_WIDTH
-    .unreq          INPUT_DATA
-    .unreq          OUTPUT_DATA
-    .unreq          OUTPTR
-    .unreq          INPTR
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMPDUP
-
-
-/*****************************************************************************/
-
-/*
- * Downsample pixel values of a single component.
- * This version handles the common case of 2:1 horizontal and 2:1 vertical,
- * without smoothing.
- *
- * GLOBAL(void)
- * jsimd_h2v2_downsample_neon(JDIMENSION image_width, int max_v_samp_factor,
- *                            JDIMENSION v_samp_factor,
- *                            JDIMENSION width_in_blocks,
- *                            JSAMPARRAY input_data, JSAMPARRAY output_data);
- */
-
-.balign 16
-asm_function jsimd_h2v2_downsample_neon
-    IMAGE_WIDTH     .req x0
-    MAX_V_SAMP      .req x1
-    V_SAMP          .req x2
-    BLOCK_WIDTH     .req x3
-    INPUT_DATA      .req x4
-    OUTPUT_DATA     .req x5
-    OUTPTR          .req x9
-    INPTR0          .req x10
-    INPTR1          .req x14
-    TMP1            .req x11
-    TMP2            .req x12
-    TMP3            .req x13
-    TMPDUP          .req w15
-
-    mov             TMPDUP, #1
-    lsl             TMP2, BLOCK_WIDTH, #4
-    lsl             TMPDUP, TMPDUP, #17
-    sub             TMP2, TMP2, IMAGE_WIDTH
-    adr             TMP3, Ljsimd_h2_downsample_neon_consts
-    orr             TMPDUP, TMPDUP, #1
-    add             TMP3, TMP3, TMP2, lsl #4
-    dup             v16.4s, TMPDUP
-    ld1             {v18.16b}, [TMP3]
-
-1:  /* row loop */
-    ldr             INPTR0, [INPUT_DATA], #8
-    ldr             OUTPTR, [OUTPUT_DATA], #8
-    ldr             INPTR1, [INPUT_DATA], #8
-    subs            TMP1, BLOCK_WIDTH, #1
-    b.eq            3f
-2:  /* columns */
-    ld1             {v0.16b}, [INPTR0], #16
-    ld1             {v1.16b}, [INPTR1], #16
-    mov             v4.16b, v16.16b
-    subs            TMP1, TMP1, #1
-    uadalp          v4.8h, v0.16b
-    uadalp          v4.8h, v1.16b
-    shrn            v6.8b, v4.8h, #2
-    st1             {v6.8b}, [OUTPTR], #8
-    b.ne            2b
-3:  /* last columns */
-    ld1             {v0.16b}, [INPTR0], #16
-    ld1             {v1.16b}, [INPTR1], #16
-    mov             v4.16b, v16.16b
-    subs            V_SAMP, V_SAMP, #1
-    /* expand right */
-    tbl             v2.16b, {v0.16b}, v18.16b
-    tbl             v3.16b, {v1.16b}, v18.16b
-    uadalp          v4.8h, v2.16b
-    uadalp          v4.8h, v3.16b
-    shrn            v6.8b, v4.8h, #2
-    st1             {v6.8b}, [OUTPTR], #8
-    b.ne            1b
-
-    br              x30
-
-    .unreq          IMAGE_WIDTH
-    .unreq          MAX_V_SAMP
-    .unreq          V_SAMP
-    .unreq          BLOCK_WIDTH
-    .unreq          INPUT_DATA
-    .unreq          OUTPUT_DATA
-    .unreq          OUTPTR
-    .unreq          INPTR0
-    .unreq          INPTR1
-    .unreq          TMP1
-    .unreq          TMP2
-    .unreq          TMP3
-    .unreq          TMPDUP
-
-
-/*****************************************************************************/
-
-/*
- * GLOBAL(JOCTET *)
- * jsimd_huff_encode_one_block(working_state *state, JOCTET *buffer,
- *                             JCOEFPTR block, int last_dc_val,
- *                             c_derived_tbl *dctbl, c_derived_tbl *actbl)
- *
- */
-
-    BUFFER          .req x1
-    PUT_BUFFER      .req x6
-    PUT_BITS        .req x7
-    PUT_BITSw       .req w7
-
-.macro emit_byte
-    sub             PUT_BITS, PUT_BITS, #0x8
-    lsr             x19, PUT_BUFFER, PUT_BITS
-    uxtb            w19, w19
-    strb            w19, [BUFFER, #1]!
-    cmp             w19, #0xff
-    b.ne            14f
-    strb            wzr, [BUFFER, #1]!
-14:
-.endm
-.macro put_bits CODE, SIZE
-    lsl             PUT_BUFFER, PUT_BUFFER, \SIZE
-    add             PUT_BITS, PUT_BITS, \SIZE
-    orr             PUT_BUFFER, PUT_BUFFER, \CODE
-.endm
-.macro checkbuf31
-    cmp             PUT_BITS, #0x20
-    b.lt            31f
-    emit_byte
-    emit_byte
-    emit_byte
-    emit_byte
-31:
-.endm
-.macro checkbuf47
-    cmp             PUT_BITS, #0x30
-    b.lt            47f
-    emit_byte
-    emit_byte
-    emit_byte
-    emit_byte
-    emit_byte
-    emit_byte
-47:
-.endm
-
-.macro generate_jsimd_huff_encode_one_block fast_tbl
-
-.balign 16
-.if \fast_tbl == 1
-Ljsimd_huff_encode_one_block_neon_consts:
-.else
-Ljsimd_huff_encode_one_block_neon_slowtbl_consts:
-.endif
-    .byte 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, \
-          0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
-.if \fast_tbl == 1
-    .byte    0,   1,   2,   3,  16,  17,  32,  33, \
-            18,  19,   4,   5,   6,   7,  20,  21  /* L0 => L3 : 4 lines OK */
-    .byte   34,  35,  48,  49, 255, 255,  50,  51, \
-            36,  37,  22,  23,   8,   9,  10,  11  /* L0 => L3 : 4 lines OK */
-    .byte    8,   9,  22,  23,  36,  37,  50,  51, \
-           255, 255, 255, 255, 255, 255,  52,  53  /* L1 => L4 : 4 lines OK */
-    .byte   54,  55,  40,  41,  26,  27,  12,  13, \
-            14,  15,  28,  29,  42,  43,  56,  57  /* L0 => L3 : 4 lines OK */
-    .byte    6,   7,  20,  21,  34,  35,  48,  49, \
-            50,  51,  36,  37,  22,  23,   8,   9  /* L4 => L7 : 4 lines OK */
-    .byte   42,  43,  28,  29,  14,  15,  30,  31, \
-            44,  45,  58,  59, 255, 255, 255, 255  /* L1 => L4 : 4 lines OK */
-    .byte  255, 255, 255, 255,  56,  57,  42,  43, \
-            28,  29,  14,  15,  30,  31,  44,  45  /* L3 => L6 : 4 lines OK */
-    .byte   26,  27,  40,  41,  42,  43,  28,  29, \
-            14,  15,  30,  31,  44,  45,  46,  47  /* L5 => L7 : 3 lines OK */
-    .byte  255, 255, 255, 255,   0,   1, 255, 255, \
-           255, 255, 255, 255, 255, 255, 255, 255  /* L4 : 1 lines OK */
-    .byte  255, 255, 255, 255, 255, 255, 255, 255, \
-             0,   1,  16,  17,   2,   3, 255, 255  /* L5 => L6 : 2 lines OK */
-    .byte  255, 255, 255, 255, 255, 255, 255, 255, \
-           255, 255, 255, 255,   8,   9,  22,  23  /* L5 => L6 : 2 lines OK */
-    .byte    4,   5,   6,   7, 255, 255, 255, 255, \
-           255, 255, 255, 255, 255, 255, 255, 255  /* L7 : 1 line OK */
-.endif
-
-.if \fast_tbl == 1
-asm_function jsimd_huff_encode_one_block_neon
-.else
-asm_function jsimd_huff_encode_one_block_neon_slowtbl
-.endif
-    sub             sp, sp, 272
-    sub             BUFFER, BUFFER, #0x1    /* BUFFER=buffer-- */
-    /* Save ARM registers */
-    stp             x19, x20, [sp]
-.if \fast_tbl == 1
-    adr             x15, Ljsimd_huff_encode_one_block_neon_consts
-.else
-    adr             x15, Ljsimd_huff_encode_one_block_neon_slowtbl_consts
-.endif
-    ldr             PUT_BUFFER, [x0, #0x10]
-    ldr             PUT_BITSw, [x0, #0x18]
-    ldrsh           w12, [x2]               /* load DC coeff in w12 */
-    /* prepare data */
-.if \fast_tbl == 1
-    ld1             {v23.16b}, [x15], #16
-    ld1             {v0.16b, v1.16b, v2.16b, v3.16b}, [x15], #64
-    ld1             {v4.16b, v5.16b, v6.16b, v7.16b}, [x15], #64
-    ld1             {v16.16b, v17.16b, v18.16b, v19.16b}, [x15], #64
-    ld1             {v24.16b, v25.16b, v26.16b, v27.16b}, [x2], #64
-    ld1             {v28.16b, v29.16b, v30.16b, v31.16b}, [x2], #64
-    sub             w12, w12, w3      /* last_dc_val, not used afterwards */
-    /* ZigZag 8x8 */
-    tbl             v0.16b, {v24.16b, v25.16b, v26.16b, v27.16b}, v0.16b
-    tbl             v1.16b, {v24.16b, v25.16b, v26.16b, v27.16b}, v1.16b
-    tbl             v2.16b, {v25.16b, v26.16b, v27.16b, v28.16b}, v2.16b
-    tbl             v3.16b, {v24.16b, v25.16b, v26.16b, v27.16b}, v3.16b
-    tbl             v4.16b, {v28.16b, v29.16b, v30.16b, v31.16b}, v4.16b
-    tbl             v5.16b, {v25.16b, v26.16b, v27.16b, v28.16b}, v5.16b
-    tbl             v6.16b, {v27.16b, v28.16b, v29.16b, v30.16b}, v6.16b
-    tbl             v7.16b, {v29.16b, v30.16b, v31.16b}, v7.16b
-    ins             v0.h[0], w12
-    tbx             v1.16b, {v28.16b}, v16.16b
-    tbx             v2.16b, {v29.16b, v30.16b}, v17.16b
-    tbx             v5.16b, {v29.16b, v30.16b}, v18.16b
-    tbx             v6.16b, {v31.16b}, v19.16b
-.else
-      add             x13, x2, #0x22
-      sub             w12, w12, w3    /* last_dc_val, not used afterwards */
-    ld1             {v23.16b}, [x15]
-      add             x14, x2, #0x18
-      add             x3, x2, #0x36
-    ins             v0.h[0], w12
-      add             x9, x2, #0x2
-    ld1             {v1.h}[0], [x13]
-      add             x15, x2, #0x30
-    ld1             {v2.h}[0], [x14]
-      add             x19, x2, #0x26
-    ld1             {v3.h}[0], [x3]
-      add             x20, x2, #0x28
-    ld1             {v0.h}[1], [x9]
-      add             x12, x2, #0x10
-    ld1             {v1.h}[1], [x15]
-      add             x13, x2, #0x40
-    ld1             {v2.h}[1], [x19]
-      add             x14, x2, #0x34
-    ld1             {v3.h}[1], [x20]
-      add             x3, x2, #0x1a
-    ld1             {v0.h}[2], [x12]
-      add             x9, x2, #0x20
-    ld1             {v1.h}[2], [x13]
-      add             x15, x2, #0x32
-    ld1             {v2.h}[2], [x14]
-      add             x19, x2, #0x42
-    ld1             {v3.h}[2], [x3]
-      add             x20, x2, #0xc
-    ld1             {v0.h}[3], [x9]
-      add             x12, x2, #0x12
-    ld1             {v1.h}[3], [x15]
-      add             x13, x2, #0x24
-    ld1             {v2.h}[3], [x19]
-      add             x14, x2, #0x50
-    ld1             {v3.h}[3], [x20]
-      add             x3, x2, #0xe
-    ld1             {v0.h}[4], [x12]
-      add             x9, x2, #0x4
-    ld1             {v1.h}[4], [x13]
-      add             x15, x2, #0x16
-    ld1             {v2.h}[4], [x14]
-      add             x19, x2, #0x60
-    ld1             {v3.h}[4], [x3]
-      add             x20, x2, #0x1c
-    ld1             {v0.h}[5], [x9]
-      add             x12, x2, #0x6
-    ld1             {v1.h}[5], [x15]
-      add             x13, x2, #0x8
-    ld1             {v2.h}[5], [x19]
-      add             x14, x2, #0x52
-    ld1             {v3.h}[5], [x20]
-      add             x3, x2, #0x2a
-    ld1             {v0.h}[6], [x12]
-      add             x9, x2, #0x14
-    ld1             {v1.h}[6], [x13]
-      add             x15, x2, #0xa
-    ld1             {v2.h}[6], [x14]
-      add             x19, x2, #0x44
-    ld1             {v3.h}[6], [x3]
-      add             x20, x2, #0x38
-    ld1             {v0.h}[7], [x9]
-      add             x12, x2, #0x46
-    ld1             {v1.h}[7], [x15]
-      add             x13, x2, #0x3a
-    ld1             {v2.h}[7], [x19]
-      add             x14, x2, #0x74
-    ld1             {v3.h}[7], [x20]
-      add             x3, x2, #0x6a
-    ld1             {v4.h}[0], [x12]
-      add             x9, x2, #0x54
-    ld1             {v5.h}[0], [x13]
-      add             x15, x2, #0x2c
-    ld1             {v6.h}[0], [x14]
-      add             x19, x2, #0x76
-    ld1             {v7.h}[0], [x3]
-      add             x20, x2, #0x78
-    ld1             {v4.h}[1], [x9]
-      add             x12, x2, #0x62
-    ld1             {v5.h}[1], [x15]
-      add             x13, x2, #0x1e
-    ld1             {v6.h}[1], [x19]
-      add             x14, x2, #0x68
-    ld1             {v7.h}[1], [x20]
-      add             x3, x2, #0x7a
-    ld1             {v4.h}[2], [x12]
-      add             x9, x2, #0x70
-    ld1             {v5.h}[2], [x13]
-      add             x15, x2, #0x2e
-    ld1             {v6.h}[2], [x14]
-      add             x19, x2, #0x5a
-    ld1             {v7.h}[2], [x3]
-      add             x20, x2, #0x6c
-    ld1             {v4.h}[3], [x9]
-      add             x12, x2, #0x72
-    ld1             {v5.h}[3], [x15]
-      add             x13, x2, #0x3c
-    ld1             {v6.h}[3], [x19]
-      add             x14, x2, #0x4c
-    ld1             {v7.h}[3], [x20]
-      add             x3, x2, #0x5e
-    ld1             {v4.h}[4], [x12]
-      add             x9, x2, #0x64
-    ld1             {v5.h}[4], [x13]
-      add             x15, x2, #0x4a
-    ld1             {v6.h}[4], [x14]
-      add             x19, x2, #0x3e
-    ld1             {v7.h}[4], [x3]
-      add             x20, x2, #0x6e
-    ld1             {v4.h}[5], [x9]
-      add             x12, x2, #0x56
-    ld1             {v5.h}[5], [x15]
-      add             x13, x2, #0x58
-    ld1             {v6.h}[5], [x19]
-      add             x14, x2, #0x4e
-    ld1             {v7.h}[5], [x20]
-      add             x3, x2, #0x7c
-    ld1             {v4.h}[6], [x12]
-      add             x9, x2, #0x48
-    ld1             {v5.h}[6], [x13]
-      add             x15, x2, #0x66
-    ld1             {v6.h}[6], [x14]
-      add             x19, x2, #0x5c
-    ld1             {v7.h}[6], [x3]
-      add             x20, x2, #0x7e
-    ld1             {v4.h}[7], [x9]
-    ld1             {v5.h}[7], [x15]
-    ld1             {v6.h}[7], [x19]
-    ld1             {v7.h}[7], [x20]
-.endif
-    cmlt            v24.8h, v0.8h, #0
-    cmlt            v25.8h, v1.8h, #0
-    cmlt            v26.8h, v2.8h, #0
-    cmlt            v27.8h, v3.8h, #0
-    cmlt            v28.8h, v4.8h, #0
-    cmlt            v29.8h, v5.8h, #0
-    cmlt            v30.8h, v6.8h, #0
-    cmlt            v31.8h, v7.8h, #0
-    abs             v0.8h, v0.8h
-    abs             v1.8h, v1.8h
-    abs             v2.8h, v2.8h
-    abs             v3.8h, v3.8h
-    abs             v4.8h, v4.8h
-    abs             v5.8h, v5.8h
-    abs             v6.8h, v6.8h
-    abs             v7.8h, v7.8h
-    eor             v24.16b, v24.16b, v0.16b
-    eor             v25.16b, v25.16b, v1.16b
-    eor             v26.16b, v26.16b, v2.16b
-    eor             v27.16b, v27.16b, v3.16b
-    eor             v28.16b, v28.16b, v4.16b
-    eor             v29.16b, v29.16b, v5.16b
-    eor             v30.16b, v30.16b, v6.16b
-    eor             v31.16b, v31.16b, v7.16b
-    cmeq            v16.8h, v0.8h, #0
-    cmeq            v17.8h, v1.8h, #0
-    cmeq            v18.8h, v2.8h, #0
-    cmeq            v19.8h, v3.8h, #0
-    cmeq            v20.8h, v4.8h, #0
-    cmeq            v21.8h, v5.8h, #0
-    cmeq            v22.8h, v6.8h, #0
-    xtn             v16.8b, v16.8h
-    xtn             v18.8b, v18.8h
-    xtn             v20.8b, v20.8h
-    xtn             v22.8b, v22.8h
-      umov            w14, v0.h[0]
-    xtn2            v16.16b, v17.8h
-      umov            w13, v24.h[0]
-    xtn2            v18.16b, v19.8h
-      clz             w14, w14
-    xtn2            v20.16b, v21.8h
-      lsl             w13, w13, w14
-    cmeq            v17.8h, v7.8h, #0
-      sub             w12, w14, #32
-    xtn2            v22.16b, v17.8h
-      lsr             w13, w13, w14
-    and             v16.16b, v16.16b, v23.16b
-      neg             w12, w12
-    and             v18.16b, v18.16b, v23.16b
-      add             x3, x4, #0x400           /* r1 = dctbl->ehufsi */
-    and             v20.16b, v20.16b, v23.16b
-      add             x15, sp, #0x90           /* x15 = t2 */
-    and             v22.16b, v22.16b, v23.16b
-      ldr             w10, [x4, x12, lsl #2]
-    addp            v16.16b, v16.16b, v18.16b
-      ldrb            w11, [x3, x12]
-    addp            v20.16b, v20.16b, v22.16b
-      checkbuf47
-    addp            v16.16b, v16.16b, v20.16b
-      put_bits        x10, x11
-    addp            v16.16b, v16.16b, v18.16b
-      checkbuf47
-    umov            x9, v16.D[0]
-      put_bits        x13, x12
-    cnt             v17.8b, v16.8b
-      mvn             x9, x9
-    addv            B18, v17.8b
-      add             x4, x5, #0x400   /* x4 = actbl->ehufsi */
-    umov            w12, v18.b[0]
-      lsr             x9, x9, #0x1     /* clear AC coeff */
-    ldr             w13, [x5, #0x3c0]  /* x13 = actbl->ehufco[0xf0] */
-    rbit            x9, x9             /* x9 = index0 */
-    ldrb            w14, [x4, #0xf0]   /* x14 = actbl->ehufsi[0xf0] */
-    cmp             w12, #(64-8)
-    add             x11, sp, #16
-    b.lt            4f
-    cbz             x9, 6f
-    st1             {v0.8h, v1.8h, v2.8h, v3.8h}, [x11], #64
-    st1             {v4.8h, v5.8h, v6.8h, v7.8h}, [x11], #64
-    st1             {v24.8h, v25.8h, v26.8h, v27.8h}, [x11], #64
-    st1             {v28.8h, v29.8h, v30.8h, v31.8h}, [x11], #64
-1:
-    clz             x2, x9
-    add             x15, x15, x2, lsl #1
-    lsl             x9, x9, x2
-    ldrh            w20, [x15, #-126]
-2:
-    cmp             x2, #0x10
-    b.lt            3f
-    sub             x2, x2, #0x10
-    checkbuf47
-    put_bits        x13, x14
-    b               2b
-3:
-    clz             w20, w20
-    ldrh            w3, [x15, #2]!
-    sub             w11, w20, #32
-    lsl             w3, w3, w20
-    neg             w11, w11
-    lsr             w3, w3, w20
-    add             x2, x11, x2, lsl #4
-    lsl             x9, x9, #0x1
-    ldr             w12, [x5, x2, lsl #2]
-    ldrb            w10, [x4, x2]
-    checkbuf31
-    put_bits        x12, x10
-    put_bits        x3, x11
-    cbnz            x9, 1b
-    b               6f
-4:
-    movi            v21.8h, #0x0010
-    clz             v0.8h, v0.8h
-    clz             v1.8h, v1.8h
-    clz             v2.8h, v2.8h
-    clz             v3.8h, v3.8h
-    clz             v4.8h, v4.8h
-    clz             v5.8h, v5.8h
-    clz             v6.8h, v6.8h
-    clz             v7.8h, v7.8h
-    ushl            v24.8h, v24.8h, v0.8h
-    ushl            v25.8h, v25.8h, v1.8h
-    ushl            v26.8h, v26.8h, v2.8h
-    ushl            v27.8h, v27.8h, v3.8h
-    ushl            v28.8h, v28.8h, v4.8h
-    ushl            v29.8h, v29.8h, v5.8h
-    ushl            v30.8h, v30.8h, v6.8h
-    ushl            v31.8h, v31.8h, v7.8h
-    neg             v0.8h, v0.8h
-    neg             v1.8h, v1.8h
-    neg             v2.8h, v2.8h
-    neg             v3.8h, v3.8h
-    neg             v4.8h, v4.8h
-    neg             v5.8h, v5.8h
-    neg             v6.8h, v6.8h
-    neg             v7.8h, v7.8h
-    ushl            v24.8h, v24.8h, v0.8h
-    ushl            v25.8h, v25.8h, v1.8h
-    ushl            v26.8h, v26.8h, v2.8h
-    ushl            v27.8h, v27.8h, v3.8h
-    ushl            v28.8h, v28.8h, v4.8h
-    ushl            v29.8h, v29.8h, v5.8h
-    ushl            v30.8h, v30.8h, v6.8h
-    ushl            v31.8h, v31.8h, v7.8h
-    add             v0.8h, v21.8h, v0.8h
-    add             v1.8h, v21.8h, v1.8h
-    add             v2.8h, v21.8h, v2.8h
-    add             v3.8h, v21.8h, v3.8h
-    add             v4.8h, v21.8h, v4.8h
-    add             v5.8h, v21.8h, v5.8h
-    add             v6.8h, v21.8h, v6.8h
-    add             v7.8h, v21.8h, v7.8h
-    st1             {v0.8h, v1.8h, v2.8h, v3.8h}, [x11], #64
-    st1             {v4.8h, v5.8h, v6.8h, v7.8h}, [x11], #64
-    st1             {v24.8h, v25.8h, v26.8h, v27.8h}, [x11], #64
-    st1             {v28.8h, v29.8h, v30.8h, v31.8h}, [x11], #64
-1:
-    clz             x2, x9
-    add             x15, x15, x2, lsl #1
-    lsl             x9, x9, x2
-    ldrh            w11, [x15, #-126]
-2:
-    cmp             x2, #0x10
-    b.lt            3f
-    sub             x2, x2, #0x10
-    checkbuf47
-    put_bits        x13, x14
-    b               2b
-3:
-    ldrh            w3, [x15, #2]!
-    add             x2, x11, x2, lsl #4
-    lsl             x9, x9, #0x1
-    ldr             w12, [x5, x2, lsl #2]
-    ldrb            w10, [x4, x2]
-    checkbuf31
-    put_bits        x12, x10
-    put_bits        x3, x11
-    cbnz            x9, 1b
-6:
-    add             x13, sp, #0x10e
-    cmp             x15, x13
-    b.hs            1f
-    ldr             w12, [x5]
-    ldrb            w14, [x4]
-    checkbuf47
-    put_bits        x12, x14
-1:
-    str             PUT_BUFFER, [x0, #0x10]
-    str             PUT_BITSw, [x0, #0x18]
-    ldp             x19, x20, [sp], 16
-    add             x0, BUFFER, #0x1
-    add             sp, sp, 256
-    br              x30
-
-.endm
-
-generate_jsimd_huff_encode_one_block 1
-generate_jsimd_huff_encode_one_block 0
-
-    .unreq          BUFFER
-    .unreq          PUT_BUFFER
-    .unreq          PUT_BITS
-    .unreq          PUT_BITSw
-
-.purgem emit_byte
-.purgem put_bits
-.purgem checkbuf31
-.purgem checkbuf47
diff --git a/src/third_party/libjpeg-turbo/simd/gas-preprocessor.in b/src/third_party/libjpeg-turbo/simd/gas-preprocessor.in
deleted file mode 100755
index 560f788..0000000
--- a/src/third_party/libjpeg-turbo/simd/gas-preprocessor.in
+++ /dev/null
@@ -1 +0,0 @@
-gas-preprocessor.pl @CMAKE_ASM_COMPILER@ ${1+"$@"}
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolext-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolext-avx2.asm
index 7a8d784..c46d684 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolext-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -110,12 +108,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
-    movzx       eax, BYTE [esi+ecx]
+    movzx       eax, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
-    movzx       edx, WORD [esi+ecx]
+    movzx       edx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolext-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolext-mmx.asm
index 9a2c30e..6357a42 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolext-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolext-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -111,13 +109,13 @@
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
     xor         eax, eax
-    mov         al, BYTE [esi+ecx]
+    mov         al, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
     xor         edx, edx
-    mov         dx, WORD [esi+ecx]
+    mov         dx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
@@ -127,7 +125,7 @@
     test        cl, SIZEOF_DWORD
     jz          short .column_ld8
     sub         ecx, byte SIZEOF_DWORD
-    movd        mmG, DWORD [esi+ecx]
+    movd        mmG, dword [esi+ecx]
     psllq       mmA, DWORD_BIT
     por         mmA, mmG
 .column_ld8:
@@ -197,7 +195,7 @@
     test        cl, SIZEOF_MMWORD/8
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_MMWORD/8
-    movd        mmA, DWORD [esi+ecx*RGB_PIXELSIZE]
+    movd        mmA, dword [esi+ecx*RGB_PIXELSIZE]
 .column_ld2:
     test        cl, SIZEOF_MMWORD/4
     jz          short .column_ld4
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolext-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolext-sse2.asm
index e830562..c6c8085 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolext-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -109,12 +107,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
-    movzx       eax, BYTE [esi+ecx]
+    movzx       eax, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
-    movzx       edx, WORD [esi+ecx]
+    movzx       edx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolor-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolor-avx2.asm
index 958517f..14944e9 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolor-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolor-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolor-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolor-mmx.asm
index 47be9e1..8cb399b 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolor-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolor-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jccolor-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jccolor-sse2.asm
index c0d5d45..686d222 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jccolor-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jccolor-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgray-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgray-avx2.asm
index 4d66242..560ee0c 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgray-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgray-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgray-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgray-mmx.asm
index 07c7ea6..79fdf08 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgray-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgray-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgray-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgray-sse2.asm
index 4b8c797..cb4b28e 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgray-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgray-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-avx2.asm
index 52e99a8..3fa7973 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -102,12 +100,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
-    movzx       eax, BYTE [esi+ecx]
+    movzx       eax, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
-    movzx       edx, WORD [esi+ecx]
+    movzx       edx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-mmx.asm
index 4a9ab0d..8af42e5 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -103,13 +101,13 @@
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
     xor         eax, eax
-    mov         al, BYTE [esi+ecx]
+    mov         al, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
     xor         edx, edx
-    mov         dx, WORD [esi+ecx]
+    mov         dx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
@@ -119,7 +117,7 @@
     test        cl, SIZEOF_DWORD
     jz          short .column_ld8
     sub         ecx, byte SIZEOF_DWORD
-    movd        mmG, DWORD [esi+ecx]
+    movd        mmG, dword [esi+ecx]
     psllq       mmA, DWORD_BIT
     por         mmA, mmG
 .column_ld8:
@@ -189,7 +187,7 @@
     test        cl, SIZEOF_MMWORD/8
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_MMWORD/8
-    movd        mmA, DWORD [esi+ecx*RGB_PIXELSIZE]
+    movd        mmA, dword [esi+ecx*RGB_PIXELSIZE]
 .column_ld2:
     test        cl, SIZEOF_MMWORD/4
     jz          short .column_ld4
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-sse2.asm
index 04d891c..c9d6ff1 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcgryext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcgryext-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -101,12 +99,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         ecx, byte SIZEOF_BYTE
-    movzx       eax, BYTE [esi+ecx]
+    movzx       eax, byte [esi+ecx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         ecx, byte SIZEOF_WORD
-    movzx       edx, WORD [esi+ecx]
+    movzx       edx, word [esi+ecx]
     shl         eax, WORD_BIT
     or          eax, edx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jchuff-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jchuff-sse2.asm
index 6ea69f6..278cf5e 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jchuff-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jchuff-sse2.asm
@@ -1,8 +1,9 @@
 ;
 ; jchuff-sse2.asm - Huffman entropy encoding (SSE2)
 ;
-; Copyright (C) 2009-2011, 2014-2017, D. R. Commander.
+; Copyright (C) 2009-2011, 2014-2017, 2019, D. R. Commander.
 ; Copyright (C) 2015, Matthieu Darbois.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -15,136 +16,255 @@
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
 ; This file contains an SSE2 implementation for Huffman coding of one block.
-; The following code is based directly on jchuff.c; see jchuff.c for more
-; details.
-;
-; [TAB8]
+; The following code is based on jchuff.c; see jchuff.c for more details.
 
 %include "jsimdext.inc"
 
+struc working_state
+.next_output_byte:   resp 1     ; => next byte to write in buffer
+.free_in_buffer:     resp 1     ; # of byte spaces remaining in buffer
+.cur.put_buffer.simd resq 1     ; current bit accumulation buffer
+.cur.free_bits       resd 1     ; # of bits available in it
+.cur.last_dc_val     resd 4     ; last DC coef for each component
+.cinfo:              resp 1     ; dump_buffer needs access to this
+endstruc
+
+struc c_derived_tbl
+.ehufco:             resd 256   ; code for each symbol
+.ehufsi:             resb 256   ; length of code for each symbol
+; If no code has been allocated for a symbol S, ehufsi[S] contains 0
+endstruc
+
 ; --------------------------------------------------------------------------
     SECTION     SEG_CONST
 
-    alignz      32
     GLOBAL_DATA(jconst_huff_encode_one_block)
 
 EXTN(jconst_huff_encode_one_block):
 
-%include "jpeg_nbits_table.inc"
+    alignz      32
+
+jpeg_mask_bits dq 0x0000, 0x0001, 0x0003, 0x0007
+               dq 0x000f, 0x001f, 0x003f, 0x007f
+               dq 0x00ff, 0x01ff, 0x03ff, 0x07ff
+               dq 0x0fff, 0x1fff, 0x3fff, 0x7fff
+
+times 1 << 14 db 15
+times 1 << 13 db 14
+times 1 << 12 db 13
+times 1 << 11 db 12
+times 1 << 10 db 11
+times 1 <<  9 db 10
+times 1 <<  8 db  9
+times 1 <<  7 db  8
+times 1 <<  6 db  7
+times 1 <<  5 db  6
+times 1 <<  4 db  5
+times 1 <<  3 db  4
+times 1 <<  2 db  3
+times 1 <<  1 db  2
+times 1 <<  0 db  1
+times 1       db  0
+jpeg_nbits_table:
+times 1       db  0
+times 1 <<  0 db  1
+times 1 <<  1 db  2
+times 1 <<  2 db  3
+times 1 <<  3 db  4
+times 1 <<  4 db  5
+times 1 <<  5 db  6
+times 1 <<  6 db  7
+times 1 <<  7 db  8
+times 1 <<  8 db  9
+times 1 <<  9 db 10
+times 1 << 10 db 11
+times 1 << 11 db 12
+times 1 << 12 db 13
+times 1 << 13 db 14
+times 1 << 14 db 15
 
     alignz      32
 
+%ifdef PIC
+%define NBITS(x)      nbits_base + x
+%else
+%define NBITS(x)      jpeg_nbits_table + x
+%endif
+%define MASK_BITS(x)  NBITS((x) * 8) + (jpeg_mask_bits - jpeg_nbits_table)
+
 ; --------------------------------------------------------------------------
     SECTION     SEG_TEXT
     BITS        32
 
-; These macros perform the same task as the emit_bits() function in the
-; original libjpeg code.  In addition to reducing overhead by explicitly
-; inlining the code, additional performance is achieved by taking into
-; account the size of the bit buffer and waiting until it is almost full
-; before emptying it.  This mostly benefits 64-bit platforms, since 6
-; bytes can be stored in a 64-bit bit buffer before it has to be emptied.
+%define mm_put_buffer     mm0
+%define mm_all_0xff       mm1
+%define mm_temp           mm2
+%define mm_nbits          mm3
+%define mm_code_bits      mm3
+%define mm_code           mm4
+%define mm_overflow_bits  mm5
+%define mm_save_nbits     mm6
 
-%macro EMIT_BYTE 0
-    sub         put_bits, 8             ; put_bits -= 8;
-    mov         edx, put_buffer
-    mov         ecx, put_bits
-    shr         edx, cl                 ; c = (JOCTET)GETJOCTET(put_buffer >> put_bits);
-    mov         byte [eax], dl          ; *buffer++ = c;
-    add         eax, 1
-    cmp         dl, 0xFF                ; need to stuff a zero byte?
-    jne         %%.EMIT_BYTE_END
-    mov         byte [eax], 0           ; *buffer++ = 0;
-    add         eax, 1
-%%.EMIT_BYTE_END:
-%endmacro
+; Shorthand used to describe SIMD operations:
+; wN:  xmmN treated as eight signed 16-bit values
+; wN[i]:  perform the same operation on all eight signed 16-bit values, i=0..7
+; bN:  xmmN treated as 16 unsigned 8-bit values, or
+;      mmN treated as eight unsigned 8-bit values
+; bN[i]:  perform the same operation on all unsigned 8-bit values,
+;         i=0..15 (SSE register) or i=0..7 (MMX register)
+; Contents of SIMD registers are shown in memory order.
 
-%macro PUT_BITS 1
-    add         put_bits, ecx           ; put_bits += size;
-    shl         put_buffer, cl          ; put_buffer = (put_buffer << size);
-    or          put_buffer, %1
-%endmacro
+; Fill the bit buffer to capacity with the leading bits from code, then output
+; the bit buffer and put the remaining bits from code into the bit buffer.
+;
+; Usage:
+; code - contains the bits to shift into the bit buffer (LSB-aligned)
+; %1 - temp register
+; %2 - low byte of temp register
+; %3 - second byte of temp register
+; %4-%8 (optional) - extra instructions to execute before the macro completes
+; %9 - the label to which to jump when the macro completes
+;
+; Upon completion, free_bits will be set to the number of remaining bits from
+; code, and put_buffer will contain those remaining bits.  temp and code will
+; be clobbered.
+;
+; This macro encodes any 0xFF bytes as 0xFF 0x00, as does the EMIT_BYTE()
+; macro in jchuff.c.
 
-%macro CHECKBUF15 0
-    cmp         put_bits, 16            ; if (put_bits > 31) {
-    jl          %%.CHECKBUF15_END
-    mov         eax, POINTER [esp+buffer]
-    EMIT_BYTE
-    EMIT_BYTE
-    mov         POINTER [esp+buffer], eax
-%%.CHECKBUF15_END:
-%endmacro
-
-%macro EMIT_BITS 1
-    PUT_BITS    %1
-    CHECKBUF15
-%endmacro
-
-%macro kloop_prepare 37                 ;(ko, jno0, ..., jno31, xmm0, xmm1, xmm2, xmm3)
-    pxor        xmm4, xmm4              ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm5, xmm5              ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm6, xmm6              ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm7, xmm7              ; __m128i neg = _mm_setzero_si128();
-    pinsrw      %34, word [esi + %2  * SIZEOF_WORD], 0  ; xmm_shadow[0] = block[jno0];
-    pinsrw      %35, word [esi + %10 * SIZEOF_WORD], 0  ; xmm_shadow[8] = block[jno8];
-    pinsrw      %36, word [esi + %18 * SIZEOF_WORD], 0  ; xmm_shadow[16] = block[jno16];
-    pinsrw      %37, word [esi + %26 * SIZEOF_WORD], 0  ; xmm_shadow[24] = block[jno24];
-    pinsrw      %34, word [esi + %3  * SIZEOF_WORD], 1  ; xmm_shadow[1] = block[jno1];
-    pinsrw      %35, word [esi + %11 * SIZEOF_WORD], 1  ; xmm_shadow[9] = block[jno9];
-    pinsrw      %36, word [esi + %19 * SIZEOF_WORD], 1  ; xmm_shadow[17] = block[jno17];
-    pinsrw      %37, word [esi + %27 * SIZEOF_WORD], 1  ; xmm_shadow[25] = block[jno25];
-    pinsrw      %34, word [esi + %4  * SIZEOF_WORD], 2  ; xmm_shadow[2] = block[jno2];
-    pinsrw      %35, word [esi + %12 * SIZEOF_WORD], 2  ; xmm_shadow[10] = block[jno10];
-    pinsrw      %36, word [esi + %20 * SIZEOF_WORD], 2  ; xmm_shadow[18] = block[jno18];
-    pinsrw      %37, word [esi + %28 * SIZEOF_WORD], 2  ; xmm_shadow[26] = block[jno26];
-    pinsrw      %34, word [esi + %5  * SIZEOF_WORD], 3  ; xmm_shadow[3] = block[jno3];
-    pinsrw      %35, word [esi + %13 * SIZEOF_WORD], 3  ; xmm_shadow[11] = block[jno11];
-    pinsrw      %36, word [esi + %21 * SIZEOF_WORD], 3  ; xmm_shadow[19] = block[jno19];
-    pinsrw      %37, word [esi + %29 * SIZEOF_WORD], 3  ; xmm_shadow[27] = block[jno27];
-    pinsrw      %34, word [esi + %6  * SIZEOF_WORD], 4  ; xmm_shadow[4] = block[jno4];
-    pinsrw      %35, word [esi + %14 * SIZEOF_WORD], 4  ; xmm_shadow[12] = block[jno12];
-    pinsrw      %36, word [esi + %22 * SIZEOF_WORD], 4  ; xmm_shadow[20] = block[jno20];
-    pinsrw      %37, word [esi + %30 * SIZEOF_WORD], 4  ; xmm_shadow[28] = block[jno28];
-    pinsrw      %34, word [esi + %7  * SIZEOF_WORD], 5  ; xmm_shadow[5] = block[jno5];
-    pinsrw      %35, word [esi + %15 * SIZEOF_WORD], 5  ; xmm_shadow[13] = block[jno13];
-    pinsrw      %36, word [esi + %23 * SIZEOF_WORD], 5  ; xmm_shadow[21] = block[jno21];
-    pinsrw      %37, word [esi + %31 * SIZEOF_WORD], 5  ; xmm_shadow[29] = block[jno29];
-    pinsrw      %34, word [esi + %8  * SIZEOF_WORD], 6  ; xmm_shadow[6] = block[jno6];
-    pinsrw      %35, word [esi + %16 * SIZEOF_WORD], 6  ; xmm_shadow[14] = block[jno14];
-    pinsrw      %36, word [esi + %24 * SIZEOF_WORD], 6  ; xmm_shadow[22] = block[jno22];
-    pinsrw      %37, word [esi + %32 * SIZEOF_WORD], 6  ; xmm_shadow[30] = block[jno30];
-    pinsrw      %34, word [esi + %9  * SIZEOF_WORD], 7  ; xmm_shadow[7] = block[jno7];
-    pinsrw      %35, word [esi + %17 * SIZEOF_WORD], 7  ; xmm_shadow[15] = block[jno15];
-    pinsrw      %36, word [esi + %25 * SIZEOF_WORD], 7  ; xmm_shadow[23] = block[jno23];
-%if %1 != 32
-    pinsrw      %37, word [esi + %33 * SIZEOF_WORD], 7  ; xmm_shadow[31] = block[jno31];
-%else
-    pinsrw      %37, ecx, 7             ; xmm_shadow[31] = block[jno31];
+%macro EMIT_QWORD 9
+%define %%temp   %1
+%define %%tempb  %2
+%define %%temph  %3
+    add         nbits, free_bits             ; nbits += free_bits;
+    neg         free_bits                    ; free_bits = -free_bits;
+    movq        mm_temp, mm_code             ; temp = code;
+    movd        mm_nbits, nbits              ; nbits --> MMX register
+    movd        mm_overflow_bits, free_bits  ; overflow_bits (temp register) = free_bits;
+    neg         free_bits                    ; free_bits = -free_bits;
+    psllq       mm_put_buffer, mm_nbits      ; put_buffer <<= nbits;
+    psrlq       mm_temp, mm_overflow_bits    ; temp >>= overflow_bits;
+    add         free_bits, 64                ; free_bits += 64;
+    por         mm_temp, mm_put_buffer       ; temp |= put_buffer;
+%ifidn %%temp, nbits_base
+    movd        mm_save_nbits, nbits_base    ; save nbits_base
 %endif
-    pcmpgtw     xmm4, %34               ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm5, %35               ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm6, %36               ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm7, %37               ; neg = _mm_cmpgt_epi16(neg, x1);
-    paddw       %34, xmm4               ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %35, xmm5               ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %36, xmm6               ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %37, xmm7               ; x1 = _mm_add_epi16(x1, neg);
-    pxor        %34, xmm4               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %35, xmm5               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %36, xmm6               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %37, xmm7               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        xmm4, %34               ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm5, %35               ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm6, %36               ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm7, %37               ; neg = _mm_xor_si128(neg, x1);
-    movdqa      XMMWORD [esp + t1 + %1 * SIZEOF_WORD], %34          ; _mm_storeu_si128((__m128i *)(t1 + ko), x1);
-    movdqa      XMMWORD [esp + t1 + (%1 + 8) * SIZEOF_WORD], %35    ; _mm_storeu_si128((__m128i *)(t1 + ko + 8), x1);
-    movdqa      XMMWORD [esp + t1 + (%1 + 16) * SIZEOF_WORD], %36   ; _mm_storeu_si128((__m128i *)(t1 + ko + 16), x1);
-    movdqa      XMMWORD [esp + t1 + (%1 + 24) * SIZEOF_WORD], %37   ; _mm_storeu_si128((__m128i *)(t1 + ko + 24), x1);
-    movdqa      XMMWORD [esp + t2 + %1 * SIZEOF_WORD], xmm4         ; _mm_storeu_si128((__m128i *)(t2 + ko), neg);
-    movdqa      XMMWORD [esp + t2 + (%1 + 8) * SIZEOF_WORD], xmm5   ; _mm_storeu_si128((__m128i *)(t2 + ko + 8), neg);
-    movdqa      XMMWORD [esp + t2 + (%1 + 16) * SIZEOF_WORD], xmm6  ; _mm_storeu_si128((__m128i *)(t2 + ko + 16), neg);
-    movdqa      XMMWORD [esp + t2 + (%1 + 24) * SIZEOF_WORD], xmm7  ; _mm_storeu_si128((__m128i *)(t2 + ko + 24), neg);
+    movq        mm_code_bits, mm_temp        ; code_bits (temp register) = temp;
+    movq        mm_put_buffer, mm_code       ; put_buffer = code;
+    pcmpeqb     mm_temp, mm_all_0xff         ; b_temp[i] = (b_temp[i] == 0xFF ? 0xFF : 0);
+    movq        mm_code, mm_code_bits        ; code = code_bits;
+    psrlq       mm_code_bits, 32             ; code_bits >>= 32;
+    pmovmskb    nbits, mm_temp               ; nbits = 0;  nbits |= ((b_temp[i] >> 7) << i);
+    movd        %%temp, mm_code_bits         ; temp = code_bits;
+    bswap       %%temp                       ; temp = htonl(temp);
+    test        nbits, nbits                 ; if (nbits != 0)  /* Some 0xFF bytes */
+    jnz         %%.SLOW                      ;   goto %%.SLOW
+    mov         dword [buffer], %%temp       ; *(uint32_t)buffer = temp;
+%ifidn %%temp, nbits_base
+    movd        nbits_base, mm_save_nbits    ; restore nbits_base
+%endif
+    %4
+    movd        nbits, mm_code               ; nbits = (uint32_t)(code);
+    %5
+    bswap       nbits                        ; nbits = htonl(nbits);
+    mov         dword [buffer + 4], nbits    ; *(uint32_t)(buffer + 4) = nbits;
+    lea         buffer, [buffer + 8]         ; buffer += 8;
+    %6
+    %7
+    %8
+    jmp %9                                   ; return
+%%.SLOW:
+    ; Execute the equivalent of the EMIT_BYTE() macro in jchuff.c for all 8
+    ; bytes in the qword.
+    mov         byte [buffer], %%tempb     ; buffer[0] = temp[0];
+    cmp         %%tempb, 0xFF              ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], %%temph     ; buffer[0] = temp[1];
+    cmp         %%temph, 0xFF              ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    shr         %%temp, 16                 ; temp >>= 16;
+    mov         byte [buffer], %%tempb     ; buffer[0] = temp[0];
+    cmp         %%tempb, 0xFF              ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], %%temph     ; buffer[0] = temp[1];
+    cmp         %%temph, 0xFF              ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    movd        nbits, mm_code             ; nbits (temp register) = (uint32_t)(code)
+%ifidn %%temp, nbits_base
+    movd        nbits_base, mm_save_nbits  ; restore nbits_base
+%endif
+    bswap       nbits                      ; nbits = htonl(nbits)
+    mov         byte [buffer], nbitsb      ; buffer[0] = nbits[0];
+    cmp         nbitsb, 0xFF               ; Set CF if nbits[0] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (nbits[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], nbitsh      ; buffer[0] = nbits[1];
+    cmp         nbitsh, 0xFF               ; Set CF if nbits[1] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (nbits[1] < 0xFF ? 1 : 0));
+    shr         nbits, 16                  ; nbits >>= 16;
+    mov         byte [buffer], nbitsb      ; buffer[0] = nbits[0];
+    cmp         nbitsb, 0xFF               ; Set CF if nbits[0] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (nbits[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], nbitsh      ; buffer[0] = nbits[1];
+    %4
+    cmp         nbitsh, 0xFF               ; Set CF if nbits[1] < 0xFF
+    mov         byte [buffer+1], 0         ; buffer[1] = 0;
+    sbb         buffer, -2                 ; buffer -= (-2 + (nbits[1] < 0xFF ? 1 : 0));
+    %5
+    %6
+    %7
+    %8
+    jmp %9                                 ; return;
+%endmacro
+
+%macro PUSH 1
+    push        %1
+%assign stack_offset  stack_offset + 4
+%endmacro
+
+%macro POP 1
+    pop         %1
+%assign stack_offset  stack_offset - 4
+%endmacro
+
+; If PIC is defined, load the address of a symbol defined in this file into a
+; register.  Equivalent to
+;   get_GOT     %1
+;   lea         %1, [GOTOFF(%1, %2)]
+; without using the GOT.
+;
+; Usage:
+; %1 - register into which to load the address of the symbol
+; %2 - symbol whose address should be loaded
+; %3 - optional multi-line macro to execute before the symbol address is loaded
+; %4 - optional multi-line macro to execute after the symbol address is loaded
+;
+; If PIC is not defined, then %3 and %4 are executed in order.
+
+%macro GET_SYM 2-4
+%ifdef PIC
+    call        %%.geteip
+%%.ref:
+    %4
+    add         %1, %2 - %%.ref
+    jmp         short %%.done
+    align       32
+%%.geteip:
+    %3          4               ; must adjust stack pointer because of call
+    mov         %1, POINTER [esp]
+    ret
+    align       32
+%%.done:
+%else
+    %3          0
+    %4
+%endif
 %endmacro
 
 ;
@@ -155,272 +275,487 @@
 ;                                  JCOEFPTR block, int last_dc_val,
 ;                                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
 ;
+; Stack layout:
+; Function args
+; Return address
+; Saved ebx
+; Saved ebp
+; Saved esi
+; Saved edi <-- esp_save
+; ...
+; esp_save
+; t_ 64*2 bytes (aligned to 128 bytes)
+;
+; esp is used (as t) to point into t_ (data in lower indices is not used once
+; esp passes over them, so this is signal-safe.)  Aligning to 128 bytes allows
+; us to find the rest of the data again.
+;
+; NOTES:
+; When shuffling data, we try to avoid pinsrw as much as possible, since it is
+; slow on many CPUs.  Its reciprocal throughput (issue latency) is 1 even on
+; modern CPUs, so chains of pinsrw instructions (even with different outputs)
+; can limit performance.  pinsrw is a VectorPath instruction on AMD K8 and
+; requires 2 µops (with memory operand) on Intel.  In either case, only one
+; pinsrw instruction can be decoded per cycle (and nothing else if they are
+; back-to-back), so out-of-order execution cannot be used to work around long
+; pinsrw chains (though for Sandy Bridge and later, this may be less of a
+; problem if the code runs from the µop cache.)
+;
+; We use tzcnt instead of bsf without checking for support.  The instruction is
+; executed as bsf on CPUs that don't support tzcnt (encoding is equivalent to
+; rep bsf.)  The destination (first) operand of bsf (and tzcnt on some CPUs) is
+; an input dependency (although the behavior is not formally defined, Intel
+; CPUs usually leave the destination unmodified if the source is zero.)  This
+; can prevent out-of-order execution, so we clear the destination before
+; invoking tzcnt.
+;
+; Initial register allocation
+; eax - frame --> buffer
+; ebx - nbits_base (PIC) / emit_temp
+; ecx - dctbl --> size --> state
+; edx - block --> nbits
+; esi - code_temp --> state --> actbl
+; edi - index_temp --> free_bits
+; esp - t
+; ebp - index
 
-; eax + 8 = working_state *state
-; eax + 12 = JOCTET *buffer
-; eax + 16 = JCOEFPTR block
-; eax + 20 = int last_dc_val
-; eax + 24 = c_derived_tbl *dctbl
-; eax + 28 = c_derived_tbl *actbl
+%define frame       eax
+%ifdef PIC
+%define nbits_base  ebx
+%endif
+%define emit_temp   ebx
+%define emit_tempb  bl
+%define emit_temph  bh
+%define dctbl       ecx
+%define block       edx
+%define code_temp   esi
+%define index_temp  edi
+%define t           esp
+%define index       ebp
 
-%define pad         6 * SIZEOF_DWORD    ; Align to 16 bytes
-%define t1          pad
-%define t2          t1 + (DCTSIZE2 * SIZEOF_WORD)
-%define block       t2 + (DCTSIZE2 * SIZEOF_WORD)
-%define actbl       block + SIZEOF_DWORD
-%define buffer      actbl + SIZEOF_DWORD
-%define temp        buffer + SIZEOF_DWORD
-%define temp2       temp + SIZEOF_DWORD
-%define temp3       temp2 + SIZEOF_DWORD
-%define temp4       temp3 + SIZEOF_DWORD
-%define temp5       temp4 + SIZEOF_DWORD
-%define gotptr      temp5 + SIZEOF_DWORD  ; void *gotptr
-%define put_buffer  ebx
-%define put_bits    edi
+%assign save_frame  DCTSIZE2 * SIZEOF_WORD
+
+; Step 1: Re-arrange input data according to jpeg_natural_order
+; xx 01 02 03 04 05 06 07      xx 01 08 16 09 02 03 10
+; 08 09 10 11 12 13 14 15      17 24 32 25 18 11 04 05
+; 16 17 18 19 20 21 22 23      12 19 26 33 40 48 41 34
+; 24 25 26 27 28 29 30 31 ==>  27 20 13 06 07 14 21 28
+; 32 33 34 35 36 37 38 39      35 42 49 56 57 50 43 36
+; 40 41 42 43 44 45 46 47      29 22 15 23 30 37 44 51
+; 48 49 50 51 52 53 54 55      58 59 52 45 38 31 39 46
+; 56 57 58 59 60 61 62 63      53 60 61 54 47 55 62 63
 
     align       32
     GLOBAL_FUNCTION(jsimd_huff_encode_one_block_sse2)
 
 EXTN(jsimd_huff_encode_one_block_sse2):
-    push        ebp
-    mov         eax, esp                     ; eax = original ebp
-    sub         esp, byte 4
-    and         esp, byte (-SIZEOF_XMMWORD)  ; align to 128 bits
-    mov         [esp], eax
-    mov         ebp, esp                     ; ebp = aligned ebp
-    sub         esp, temp5+9*SIZEOF_DWORD-pad
-    push        ebx
-    push        ecx
-;   push        edx                     ; need not be preserved
-    push        esi
-    push        edi
-    push        ebp
 
-    mov         esi, POINTER [eax+8]       ; (working_state *state)
-    mov         put_buffer, DWORD [esi+8]  ; put_buffer = state->cur.put_buffer;
-    mov         put_bits, DWORD [esi+12]   ; put_bits = state->cur.put_bits;
-    push        esi                        ; esi is now scratch
+%assign stack_offset      0
+%define arg_state         4 + stack_offset
+%define arg_buffer        8 + stack_offset
+%define arg_block        12 + stack_offset
+%define arg_last_dc_val  16 + stack_offset
+%define arg_dctbl        20 + stack_offset
+%define arg_actbl        24 + stack_offset
 
-    get_GOT     edx                        ; get GOT address
-    movpic      POINTER [esp+gotptr], edx  ; save GOT address
+                                                          ;X: X = code stream
+    mov         block, [esp + arg_block]
+    PUSH        ebx
+    PUSH        ebp
+    movups      xmm3, XMMWORD [block + 0 * SIZEOF_WORD]   ;D: w3 = xx 01 02 03 04 05 06 07
+    PUSH        esi
+    PUSH        edi
+    movdqa      xmm0, xmm3                                ;A: w0 = xx 01 02 03 04 05 06 07
+    mov         frame, esp
+    lea         t, [frame - (save_frame + 4)]
+    movups      xmm1, XMMWORD [block + 8 * SIZEOF_WORD]   ;B: w1 = 08 09 10 11 12 13 14 15
+    and         t, -DCTSIZE2 * SIZEOF_WORD                                             ; t = &t_[0]
+    mov         [t + save_frame], frame
+    pxor        xmm4, xmm4                                ;A: w4[i] = 0;
+    punpckldq   xmm0, xmm1                                ;A: w0 = xx 01 08 09 02 03 10 11
+    pshuflw     xmm0, xmm0, 11001001b                     ;A: w0 = 01 08 xx 09 02 03 10 11
+    pinsrw      xmm0, word [block + 16 * SIZEOF_WORD], 2  ;A: w0 = 01 08 16 09 02 03 10 11
+    punpckhdq   xmm3, xmm1                                ;D: w3 = 04 05 12 13 06 07 14 15
+    punpcklqdq  xmm1, xmm3                                ;B: w1 = 08 09 10 11 04 05 12 13
+    pinsrw      xmm0, word [block + 17 * SIZEOF_WORD], 7  ;A: w0 = 01 08 16 09 02 03 10 17
+                                                          ;A:      (Row 0, offset 1)
+    pcmpgtw     xmm4, xmm0                                ;A: w4[i] = (w0[i] < 0 ? -1 : 0);
+    paddw       xmm0, xmm4                                ;A: w0[i] += w4[i];
+    movaps      XMMWORD [t + 0 * SIZEOF_WORD], xmm0       ;A: t[i] = w0[i];
 
-    mov         ecx, POINTER [eax+28]
-    mov         edx, POINTER [eax+16]
-    mov         esi, POINTER [eax+12]
-    mov         POINTER [esp+actbl], ecx
-    mov         POINTER [esp+block], edx
-    mov         POINTER [esp+buffer], esi
+    movq        xmm2, qword [block + 24 * SIZEOF_WORD]    ;B: w2 = 24 25 26 27 -- -- -- --
+    pshuflw     xmm2, xmm2, 11011000b                     ;B: w2 = 24 26 25 27 -- -- -- --
+    pslldq      xmm1, 1 * SIZEOF_WORD                     ;B: w1 = -- 08 09 10 11 04 05 12
+    movups      xmm5, XMMWORD [block + 48 * SIZEOF_WORD]  ;H: w5 = 48 49 50 51 52 53 54 55
+    movsd       xmm1, xmm2                                ;B: w1 = 24 26 25 27 11 04 05 12
+    punpcklqdq  xmm2, xmm5                                ;C: w2 = 24 26 25 27 48 49 50 51
+    pinsrw      xmm1, word [block + 32 * SIZEOF_WORD], 1  ;B: w1 = 24 32 25 27 11 04 05 12
+    pxor        xmm4, xmm4                                ;A: w4[i] = 0;
+    psrldq      xmm3, 2 * SIZEOF_WORD                     ;D: w3 = 12 13 06 07 14 15 -- --
+    pcmpeqw     xmm0, xmm4                                ;A: w0[i] = (w0[i] == 0 ? -1 : 0);
+    pinsrw      xmm1, word [block + 18 * SIZEOF_WORD], 3  ;B: w1 = 24 32 25 18 11 04 05 12
+                                                          ;        (Row 1, offset 1)
+    pcmpgtw     xmm4, xmm1                                ;B: w4[i] = (w1[i] < 0 ? -1 : 0);
+    paddw       xmm1, xmm4                                ;B: w1[i] += w4[i];
+    movaps      XMMWORD [t + 8 * SIZEOF_WORD], xmm1       ;B: t[i+8] = w1[i];
+    pxor        xmm4, xmm4                                ;B: w4[i] = 0;
+    pcmpeqw     xmm1, xmm4                                ;B: w1[i] = (w1[i] == 0 ? -1 : 0);
 
-    ; Encode the DC coefficient difference per section F.1.2.1
-    mov         esi, POINTER [esp+block]  ; block
-    movsx       ecx, word [esi]           ; temp = temp2 = block[0] - last_dc_val;
-    sub         ecx, DWORD [eax+20]
-    mov         esi, ecx
+    packsswb    xmm0, xmm1                                ;AB: b0[i] = w0[i], b0[i+8] = w1[i]
+                                                          ;    w/ signed saturation
 
-    ; This is a well-known technique for obtaining the absolute value
-    ; with out a branch.  It is derived from an assembly language technique
-    ; presented in "How to Optimize for the Pentium Processors",
-    ; Copyright (c) 1996, 1997 by Agner Fog.
-    mov         edx, ecx
-    sar         edx, 31                 ; temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
-    xor         ecx, edx                ; temp ^= temp3;
-    sub         ecx, edx                ; temp -= temp3;
+    pinsrw      xmm3, word [block + 20 * SIZEOF_WORD], 0  ;D: w3 = 20 13 06 07 14 15 -- --
+    pinsrw      xmm3, word [block + 21 * SIZEOF_WORD], 5  ;D: w3 = 20 13 06 07 14 21 -- --
+    pinsrw      xmm3, word [block + 28 * SIZEOF_WORD], 6  ;D: w3 = 20 13 06 07 14 21 28 --
+    pinsrw      xmm3, word [block + 35 * SIZEOF_WORD], 7  ;D: w3 = 20 13 06 07 14 21 28 35
+                                                          ;        (Row 3, offset 1)
+    pcmpgtw     xmm4, xmm3                                ;D: w4[i] = (w3[i] < 0 ? -1 : 0);
+    paddw       xmm3, xmm4                                ;D: w3[i] += w4[i];
+    movaps      XMMWORD [t + 24 * SIZEOF_WORD], xmm3      ;D: t[i+24] = w3[i];
+    pxor        xmm4, xmm4                                ;D: w4[i] = 0;
+    pcmpeqw     xmm3, xmm4                                ;D: w3[i] = (w3[i] == 0 ? -1 : 0);
 
-    ; For a negative input, want temp2 = bitwise complement of abs(input)
-    ; This code assumes we are on a two's complement machine
-    add         esi, edx                ; temp2 += temp3;
-    mov         DWORD [esp+temp], esi   ; backup temp2 in temp
+    pinsrw      xmm2, word [block + 19 * SIZEOF_WORD], 0  ;C: w2 = 19 26 25 27 48 49 50 51
+    pinsrw      xmm2, word [block + 33 * SIZEOF_WORD], 2  ;C: w2 = 19 26 33 27 48 49 50 51
+    pinsrw      xmm2, word [block + 40 * SIZEOF_WORD], 3  ;C: w2 = 19 26 33 40 48 49 50 51
+    pinsrw      xmm2, word [block + 41 * SIZEOF_WORD], 5  ;C: w2 = 19 26 33 40 48 41 50 51
+    pinsrw      xmm2, word [block + 34 * SIZEOF_WORD], 6  ;C: w2 = 19 26 33 40 48 41 34 51
+    pinsrw      xmm2, word [block + 27 * SIZEOF_WORD], 7  ;C: w2 = 19 26 33 40 48 41 34 27
+                                                          ;        (Row 2, offset 1)
+    pcmpgtw     xmm4, xmm2                                ;C: w4[i] = (w2[i] < 0 ? -1 : 0);
+    paddw       xmm2, xmm4                                ;C: w2[i] += w4[i];
+    movsx       code_temp, word [block]                   ;Z:     code_temp = block[0];
 
-    ; Find the number of bits needed for the magnitude of the coefficient
-    movpic      ebp, POINTER [esp+gotptr]                        ; load GOT address (ebp)
-    movzx       edx, byte [GOTOFF(ebp, jpeg_nbits_table + ecx)]  ; nbits = JPEG_NBITS(temp);
-    mov         DWORD [esp+temp2], edx                           ; backup nbits in temp2
+; %1 - stack pointer adjustment
+%macro GET_SYM_BEFORE 1
+    movaps      XMMWORD [t + 16 * SIZEOF_WORD + %1], xmm2
+                                                          ;C: t[i+16] = w2[i];
+    pxor        xmm4, xmm4                                ;C: w4[i] = 0;
+    pcmpeqw     xmm2, xmm4                                ;C: w2[i] = (w2[i] == 0 ? -1 : 0);
+    sub         code_temp, [frame + arg_last_dc_val]      ;Z:     code_temp -= last_dc_val;
 
-    ; Emit the Huffman-coded symbol for the number of bits
-    mov         ebp, POINTER [eax+24]         ; After this point, arguments are not accessible anymore
-    mov         eax,  INT [ebp + edx * 4]     ; code = dctbl->ehufco[nbits];
-    movzx       ecx, byte [ebp + edx + 1024]  ; size = dctbl->ehufsi[nbits];
-    EMIT_BITS   eax                           ; EMIT_BITS(code, size)
+    packsswb    xmm2, xmm3                                ;CD: b2[i] = w2[i], b2[i+8] = w3[i]
+                                                          ;    w/ signed saturation
 
-    mov         ecx, DWORD [esp+temp2]        ; restore nbits
+    movdqa      xmm3, xmm5                                ;H: w3 = 48 49 50 51 52 53 54 55
+    pmovmskb    index_temp, xmm2                          ;Z:     index_temp = 0;  index_temp |= ((b2[i] >> 7) << i);
+    pmovmskb    index, xmm0                               ;Z:     index = 0;  index |= ((b0[i] >> 7) << i);
+    movups      xmm0, XMMWORD [block + 56 * SIZEOF_WORD]  ;H: w0 = 56 57 58 59 60 61 62 63
+    punpckhdq   xmm3, xmm0                                ;H: w3 = 52 53 60 61 54 55 62 63
+    shl         index_temp, 16                            ;Z:     index_temp <<= 16;
+    psrldq      xmm3, 1 * SIZEOF_WORD                     ;H: w3 = 53 60 61 54 55 62 63 --
+    pxor        xmm2, xmm2                                ;H: w2[i] = 0;
+    pshuflw     xmm3, xmm3, 00111001b                     ;H: w3 = 60 61 54 53 55 62 63 --
+    or          index, index_temp                         ;Z:     index |= index_temp;
+%undef index_temp
+%define free_bits  edi
+%endmacro
 
-    ; Mask off any extra bits in code
-    mov         eax, 1
-    shl         eax, cl
-    dec         eax
-    and         eax, DWORD [esp+temp]   ; temp2 &= (((JLONG)1)<<nbits) - 1;
+%macro GET_SYM_AFTER 0
+    movq        xmm1, qword [block + 44 * SIZEOF_WORD]    ;G: w1 = 44 45 46 47 -- -- -- --
+    unpcklps    xmm5, xmm0                                ;E: w5 = 48 49 56 57 50 51 58 59
+    pxor        xmm0, xmm0                                ;H: w0[i] = 0;
+    not         index                                     ;Z:     index = ~index;
+    pinsrw      xmm3, word [block + 47 * SIZEOF_WORD], 3  ;H: w3 = 60 61 54 47 55 62 63 --
+                                                          ;        (Row 7, offset 1)
+    pcmpgtw     xmm2, xmm3                                ;H: w2[i] = (w3[i] < 0 ? -1 : 0);
+    mov         dctbl, [frame + arg_dctbl]
+    paddw       xmm3, xmm2                                ;H: w3[i] += w2[i];
+    movaps      XMMWORD [t + 56 * SIZEOF_WORD], xmm3      ;H: t[i+56] = w3[i];
+    movq        xmm4, qword [block + 36 * SIZEOF_WORD]    ;G: w4 = 36 37 38 39 -- -- -- --
+    pcmpeqw     xmm3, xmm0                                ;H: w3[i] = (w3[i] == 0 ? -1 : 0);
+    punpckldq   xmm4, xmm1                                ;G: w4 = 36 37 44 45 38 39 46 47
+    movdqa      xmm1, xmm4                                ;F: w1 = 36 37 44 45 38 39 46 47
+    pcmpeqw     mm_all_0xff, mm_all_0xff                  ;Z:     all_0xff[i] = 0xFF;
+%endmacro
 
-    ; Emit that number of bits of the value, if positive,
-    ; or the complement of its magnitude, if negative.
-    EMIT_BITS   eax                     ; EMIT_BITS(temp2, nbits)
+    GET_SYM     nbits_base, jpeg_nbits_table, GET_SYM_BEFORE, GET_SYM_AFTER
 
-    ; Prepare data
-    xor         ecx, ecx
-    mov         esi, POINTER [esp+block]
-    kloop_prepare  0,  1,  8,  16, 9,  2,  3,  10, 17, 24, 32, 25, \
-                   18, 11, 4,  5,  12, 19, 26, 33, 40, 48, 41, 34, \
-                   27, 20, 13, 6,  7,  14, 21, 28, 35, \
-                   xmm0, xmm1, xmm2, xmm3
-    kloop_prepare  32, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, \
-                   30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, \
-                   53, 60, 61, 54, 47, 55, 62, 63, 63, \
-                   xmm0, xmm1, xmm2, xmm3
+    psrldq      xmm4, 1 * SIZEOF_WORD                     ;G: w4 = 37 44 45 38 39 46 47 --
+    shufpd      xmm1, xmm5, 10b                           ;F: w1 = 36 37 44 45 50 51 58 59
+    pshufhw     xmm4, xmm4, 11010011b                     ;G: w4 = 37 44 45 38 -- 39 46 --
+    pslldq      xmm1, 1 * SIZEOF_WORD                     ;F: w1 = -- 36 37 44 45 50 51 58
+    pinsrw      xmm4, word [block + 59 * SIZEOF_WORD], 0  ;G: w4 = 59 44 45 38 -- 39 46 --
+    pshufd      xmm1, xmm1, 11011000b                     ;F: w1 = -- 36 45 50 37 44 51 58
+    cmp         code_temp, 1 << 31                        ;Z:     Set CF if code_temp < 0x80000000,
+                                                          ;Z:     i.e. if code_temp is positive
+    pinsrw      xmm4, word [block + 52 * SIZEOF_WORD], 1  ;G: w4 = 59 52 45 38 -- 39 46 --
+    movlps      xmm1, qword [block + 20 * SIZEOF_WORD]    ;F: w1 = 20 21 22 23 37 44 51 58
+    pinsrw      xmm4, word [block + 31 * SIZEOF_WORD], 4  ;G: w4 = 59 52 45 38 31 39 46 --
+    pshuflw     xmm1, xmm1, 01110010b                     ;F: w1 = 22 20 23 21 37 44 51 58
+    pinsrw      xmm4, word [block + 53 * SIZEOF_WORD], 7  ;G: w4 = 59 52 45 38 31 39 46 53
+                                                          ;        (Row 6, offset 1)
+    adc         code_temp, -1                             ;Z:     code_temp += -1 + (code_temp >= 0 ? 1 : 0);
+    pxor        xmm2, xmm2                                ;G: w2[i] = 0;
+    pcmpgtw     xmm0, xmm4                                ;G: w0[i] = (w4[i] < 0 ? -1 : 0);
+    pinsrw      xmm1, word [block + 15 * SIZEOF_WORD], 1  ;F: w1 = 22 15 23 21 37 44 51 58
+    paddw       xmm4, xmm0                                ;G: w4[i] += w0[i];
+    movaps      XMMWORD [t + 48 * SIZEOF_WORD], xmm4      ;G: t[48+i] = w4[i];
+    movd        mm_temp, code_temp                        ;Z:     temp = code_temp
+    pinsrw      xmm1, word [block + 30 * SIZEOF_WORD], 3  ;F: w1 = 22 15 23 30 37 44 51 58
+                                                          ;        (Row 5, offset 1)
+    pcmpeqw     xmm4, xmm2                                ;G: w4[i] = (w4[i] == 0 ? -1 : 0);
 
-    pxor        xmm7, xmm7
-    movdqa      xmm0, XMMWORD [esp + t1 + 0 * SIZEOF_WORD]   ; __m128i tmp0 = _mm_loadu_si128((__m128i *)(t1 + 0));
-    movdqa      xmm1, XMMWORD [esp + t1 + 8 * SIZEOF_WORD]   ; __m128i tmp1 = _mm_loadu_si128((__m128i *)(t1 + 8));
-    movdqa      xmm2, XMMWORD [esp + t1 + 16 * SIZEOF_WORD]  ; __m128i tmp2 = _mm_loadu_si128((__m128i *)(t1 + 16));
-    movdqa      xmm3, XMMWORD [esp + t1 + 24 * SIZEOF_WORD]  ; __m128i tmp3 = _mm_loadu_si128((__m128i *)(t1 + 24));
-    pcmpeqw     xmm0, xmm7              ; tmp0 = _mm_cmpeq_epi16(tmp0, zero);
-    pcmpeqw     xmm1, xmm7              ; tmp1 = _mm_cmpeq_epi16(tmp1, zero);
-    pcmpeqw     xmm2, xmm7              ; tmp2 = _mm_cmpeq_epi16(tmp2, zero);
-    pcmpeqw     xmm3, xmm7              ; tmp3 = _mm_cmpeq_epi16(tmp3, zero);
-    packsswb    xmm0, xmm1              ; tmp0 = _mm_packs_epi16(tmp0, tmp1);
-    packsswb    xmm2, xmm3              ; tmp2 = _mm_packs_epi16(tmp2, tmp3);
-    pmovmskb    edx, xmm0               ; index  = ((uint64_t)_mm_movemask_epi8(tmp0)) << 0;
-    pmovmskb    ecx, xmm2               ; index  = ((uint64_t)_mm_movemask_epi8(tmp2)) << 16;
-    shl         ecx, 16
-    or          edx, ecx
-    not         edx                     ; index = ~index;
+    packsswb    xmm4, xmm3                                ;GH: b4[i] = w4[i], b4[i+8] = w3[i]
+                                                          ;    w/ signed saturation
 
-    lea         esi, [esp+t1]
-    mov         ebp, POINTER [esp+actbl]  ; ebp = actbl
+    lea         t, [t - SIZEOF_WORD]                      ;Z:     t = &t[-1]
+    pxor        xmm0, xmm0                                ;F: w0[i] = 0;
+    pcmpgtw     xmm2, xmm1                                ;F: w2[i] = (w1[i] < 0 ? -1 : 0);
+    paddw       xmm1, xmm2                                ;F: w1[i] += w2[i];
+    movaps      XMMWORD [t + (40+1) * SIZEOF_WORD], xmm1  ;F: t[40+i] = w1[i];
+    pcmpeqw     xmm1, xmm0                                ;F: w1[i] = (w1[i] == 0 ? -1 : 0);
+    pinsrw      xmm5, word [block + 42 * SIZEOF_WORD], 0  ;E: w5 = 42 49 56 57 50 51 58 59
+    pinsrw      xmm5, word [block + 43 * SIZEOF_WORD], 5  ;E: w5 = 42 49 56 57 50 43 58 59
+    pinsrw      xmm5, word [block + 36 * SIZEOF_WORD], 6  ;E: w5 = 42 49 56 57 50 43 36 59
+    pinsrw      xmm5, word [block + 29 * SIZEOF_WORD], 7  ;E: w5 = 42 49 56 57 50 43 36 29
+                                                          ;        (Row 4, offset 1)
+%undef block
+%define nbits  edx
+%define nbitsb  dl
+%define nbitsh  dh
+    movzx       nbits, byte [NBITS(code_temp)]            ;Z:     nbits = JPEG_NBITS(code_temp);
+%undef code_temp
+%define state  esi
+    pxor        xmm2, xmm2                                ;E: w2[i] = 0;
+    mov         state, [frame + arg_state]
+    movd        mm_nbits, nbits                           ;Z:     nbits --> MMX register
+    pcmpgtw     xmm0, xmm5                                ;E: w0[i] = (w5[i] < 0 ? -1 : 0);
+    movd        mm_code, dword [dctbl + c_derived_tbl.ehufco + nbits * 4]
+                                                          ;Z:     code = dctbl->ehufco[nbits];
+%define size  ecx
+%define sizeb  cl
+%define sizeh  ch
+    paddw       xmm5, xmm0                                ;E: w5[i] += w0[i];
+    movaps      XMMWORD [t + (32+1) * SIZEOF_WORD], xmm5  ;E: t[32+i] = w5[i];
+    movzx       size, byte [dctbl + c_derived_tbl.ehufsi + nbits]
+                                                          ;Z:     size = dctbl->ehufsi[nbits];
+%undef dctbl
+    pcmpeqw     xmm5, xmm2                                ;E: w5[i] = (w5[i] == 0 ? -1 : 0);
 
-.BLOOP:
-    bsf         ecx, edx                ; r = __builtin_ctzl(index);
-    jz          near .ELOOP
-    lea         esi, [esi+ecx*2]        ; k += r;
-    shr         edx, cl                 ; index >>= r;
-    mov         DWORD [esp+temp3], edx
-.BRLOOP:
-    cmp         ecx, 16                       ; while (r > 15) {
-    jl          near .ERLOOP
-    sub         ecx, 16                       ; r -= 16;
-    mov         DWORD [esp+temp], ecx
-    mov         eax, INT [ebp + 240 * 4]      ; code_0xf0 = actbl->ehufco[0xf0];
-    movzx       ecx, byte [ebp + 1024 + 240]  ; size_0xf0 = actbl->ehufsi[0xf0];
-    EMIT_BITS   eax                           ; EMIT_BITS(code_0xf0, size_0xf0)
-    mov         ecx, DWORD [esp+temp]
-    jmp         .BRLOOP
-.ERLOOP:
-    movsx       eax, word [esi]                                  ; temp = t1[k];
-    movpic      edx, POINTER [esp+gotptr]                        ; load GOT address (edx)
-    movzx       eax, byte [GOTOFF(edx, jpeg_nbits_table + eax)]  ; nbits = JPEG_NBITS(temp);
-    mov         DWORD [esp+temp2], eax
-    ; Emit Huffman symbol for run length / number of bits
-    shl         ecx, 4                        ; temp3 = (r << 4) + nbits;
-    add         ecx, eax
-    mov         eax,  INT [ebp + ecx * 4]     ; code = actbl->ehufco[temp3];
-    movzx       ecx, byte [ebp + ecx + 1024]  ; size = actbl->ehufsi[temp3];
-    EMIT_BITS   eax
+    packsswb    xmm5, xmm1                                ;EF: b5[i] = w5[i], b5[i+8] = w1[i]
+                                                          ;    w/ signed saturation
 
-    movsx       edx, word [esi+DCTSIZE2*2]    ; temp2 = t2[k];
-    ; Mask off any extra bits in code
-    mov         ecx, DWORD [esp+temp2]
-    mov         eax, 1
-    shl         eax, cl
-    dec         eax
-    and         eax, edx                ; temp2 &= (((JLONG)1)<<nbits) - 1;
-    EMIT_BITS   eax                     ; PUT_BITS(temp2, nbits)
-    mov         edx, DWORD [esp+temp3]
-    add         esi, 2                  ; ++k;
-    shr         edx, 1                  ; index >>= 1;
+    movq        mm_put_buffer, [state + working_state.cur.put_buffer.simd]
+                                                          ;Z:     put_buffer = state->cur.put_buffer.simd;
+    mov         free_bits, [state + working_state.cur.free_bits]
+                                                          ;Z:     free_bits = state->cur.free_bits;
+%undef state
+%define actbl  esi
+    mov         actbl, [frame + arg_actbl]
+%define buffer  eax
+    mov         buffer, [frame + arg_buffer]
+%undef frame
+    jmp        .BEGIN
 
-    jmp         .BLOOP
-.ELOOP:
-    movdqa      xmm0, XMMWORD [esp + t1 + 32 * SIZEOF_WORD]  ; __m128i tmp0 = _mm_loadu_si128((__m128i *)(t1 + 0));
-    movdqa      xmm1, XMMWORD [esp + t1 + 40 * SIZEOF_WORD]  ; __m128i tmp1 = _mm_loadu_si128((__m128i *)(t1 + 8));
-    movdqa      xmm2, XMMWORD [esp + t1 + 48 * SIZEOF_WORD]  ; __m128i tmp2 = _mm_loadu_si128((__m128i *)(t1 + 16));
-    movdqa      xmm3, XMMWORD [esp + t1 + 56 * SIZEOF_WORD]  ; __m128i tmp3 = _mm_loadu_si128((__m128i *)(t1 + 24));
-    pcmpeqw     xmm0, xmm7              ; tmp0 = _mm_cmpeq_epi16(tmp0, zero);
-    pcmpeqw     xmm1, xmm7              ; tmp1 = _mm_cmpeq_epi16(tmp1, zero);
-    pcmpeqw     xmm2, xmm7              ; tmp2 = _mm_cmpeq_epi16(tmp2, zero);
-    pcmpeqw     xmm3, xmm7              ; tmp3 = _mm_cmpeq_epi16(tmp3, zero);
-    packsswb    xmm0, xmm1              ; tmp0 = _mm_packs_epi16(tmp0, tmp1);
-    packsswb    xmm2, xmm3              ; tmp2 = _mm_packs_epi16(tmp2, tmp3);
-    pmovmskb    edx, xmm0               ; index  = ((uint64_t)_mm_movemask_epi8(tmp0)) << 0;
-    pmovmskb    ecx, xmm2               ; index  = ((uint64_t)_mm_movemask_epi8(tmp2)) << 16;
-    shl         ecx, 16
-    or          edx, ecx
-    not         edx                     ; index = ~index;
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    lea         eax, [esp + t1 + (DCTSIZE2/2) * 2]
-    sub         eax, esi
-    shr         eax, 1
-    bsf         ecx, edx                ; r = __builtin_ctzl(index);
-    jz          near .ELOOP2
-    shr         edx, cl                 ; index >>= r;
-    add         ecx, eax
-    lea         esi, [esi+ecx*2]        ; k += r;
-    mov         DWORD [esp+temp3], edx
-    jmp         .BRLOOP2
-.BLOOP2:
-    bsf         ecx, edx                ; r = __builtin_ctzl(index);
-    jz          near .ELOOP2
-    lea         esi, [esi+ecx*2]        ; k += r;
-    shr         edx, cl                 ; index >>= r;
-    mov         DWORD [esp+temp3], edx
-.BRLOOP2:
-    cmp         ecx, 16                       ; while (r > 15) {
-    jl          near .ERLOOP2
-    sub         ecx, 16                       ; r -= 16;
-    mov         DWORD [esp+temp], ecx
-    mov         eax, INT [ebp + 240 * 4]      ; code_0xf0 = actbl->ehufco[0xf0];
-    movzx       ecx, byte [ebp + 1024 + 240]  ; size_0xf0 = actbl->ehufsi[0xf0];
-    EMIT_BITS   eax                           ; EMIT_BITS(code_0xf0, size_0xf0)
-    mov         ecx, DWORD [esp+temp]
-    jmp         .BRLOOP2
-.ERLOOP2:
-    movsx       eax, word [esi]         ; temp = t1[k];
-    bsr         eax, eax                ; nbits = 32 - __builtin_clz(temp);
-    inc         eax
-    mov         DWORD [esp+temp2], eax
-    ; Emit Huffman symbol for run length / number of bits
-    shl         ecx, 4                        ; temp3 = (r << 4) + nbits;
-    add         ecx, eax
-    mov         eax,  INT [ebp + ecx * 4]     ; code = actbl->ehufco[temp3];
-    movzx       ecx, byte [ebp + ecx + 1024]  ; size = actbl->ehufsi[temp3];
-    EMIT_BITS   eax
+    align       16
+; size <= 32, so this is not really a loop
+.BRLOOP1:                                                 ; .BRLOOP1:
+    movzx       nbits, byte [actbl + c_derived_tbl.ehufsi + 0xf0]
+                                                          ; nbits = actbl->ehufsi[0xf0];
+    movd        mm_code, dword [actbl + c_derived_tbl.ehufco + 0xf0 * 4]
+                                                          ; code = actbl->ehufco[0xf0];
+    and         index, 0x7ffffff                          ; clear index if size == 32
+    sub         size, 16                                  ; size -= 16;
+    sub         free_bits, nbits                          ; if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_BRLOOP1                             ;   goto .EMIT_BRLOOP1;
+    movd        mm_nbits, nbits                           ; nbits --> MMX register
+    psllq       mm_put_buffer, mm_nbits                   ; put_buffer <<= nbits;
+    por         mm_put_buffer, mm_code                    ; put_buffer |= code;
+    jmp         .ERLOOP1                                  ; goto .ERLOOP1;
 
-    movsx       edx, word [esi+DCTSIZE2*2]    ; temp2 = t2[k];
-    ; Mask off any extra bits in code
-    mov         ecx, DWORD [esp+temp2]
-    mov         eax, 1
-    shl         eax, cl
-    dec         eax
-    and         eax, edx                ; temp2 &= (((JLONG)1)<<nbits) - 1;
-    EMIT_BITS   eax                     ; PUT_BITS(temp2, nbits)
-    mov         edx, DWORD [esp+temp3]
-    add         esi, 2                  ; ++k;
-    shr         edx, 1                  ; index >>= 1;
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    jmp         .BLOOP2
-.ELOOP2:
-    ; If the last coef(s) were zero, emit an end-of-block code
-    lea         edx, [esp + t1 + (DCTSIZE2-1) * 2]  ; r = DCTSIZE2-1-k;
-    cmp         edx, esi                            ; if (r > 0) {
-    je          .EFN
-    mov         eax,  INT [ebp]                     ; code = actbl->ehufco[0];
-    movzx       ecx, byte [ebp + 1024]              ; size = actbl->ehufsi[0];
-    EMIT_BITS   eax
-.EFN:
-    mov         eax, [esp+buffer]
-    pop         esi
-    ; Save put_buffer & put_bits
-    mov         DWORD [esi+8], put_buffer  ; state->cur.put_buffer = put_buffer;
-    mov         DWORD [esi+12], put_bits   ; state->cur.put_bits = put_bits;
+    align       16
+%ifdef PIC
+    times 6     nop
+%else
+    times 2     nop
+%endif
+.BLOOP1:                                                  ; do {  /* size = # of zero bits/elements to skip */
+; if size == 32, index remains unchanged.  Correct in .BRLOOP.
+    shr         index, sizeb                              ;   index >>= size;
+    lea         t, [t + size * SIZEOF_WORD]               ;   t += size;
+    cmp         size, 16                                  ;   if (size > 16)
+    jg          .BRLOOP1                                  ;     goto .BRLOOP1;
+.ERLOOP1:                                                 ; .ERLOOP1:
+    movsx       nbits, word [t]                           ;   nbits = *t;
+%ifdef PIC
+    add         size, size                                ;   size += size;
+%else
+    lea         size, [size * 2]                          ;   size += size;
+%endif
+    movd        mm_temp, nbits                            ;   temp = nbits;
+    movzx       nbits, byte [NBITS(nbits)]                ;   nbits = JPEG_NBITS(nbits);
+    lea         size, [size * 8 + nbits]                  ;   size = size * 8 + nbits;
+    movd        mm_nbits, nbits                           ;   nbits --> MMX register
+    movd        mm_code, dword [actbl + c_derived_tbl.ehufco + (size - 16) * 4]
+                                                          ;   code = actbl->ehufco[size-16];
+    movzx       size, byte [actbl + c_derived_tbl.ehufsi + (size - 16)]
+                                                          ;   size = actbl->ehufsi[size-16];
+.BEGIN:                                                   ; .BEGIN:
+    pand        mm_temp, [MASK_BITS(nbits)]               ;   temp &= (1 << nbits) - 1;
+    psllq       mm_code, mm_nbits                         ;   code <<= nbits;
+    add         nbits, size                               ;   nbits += size;
+    por         mm_code, mm_temp                          ;   code |= temp;
+    sub         free_bits, nbits                          ;   if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_ERLOOP1                             ;     insert code, flush buffer, init size, goto .BLOOP1
+    xor         size, size                                ;   size = 0;  /* kill tzcnt input dependency */
+    tzcnt       size, index                               ;   size = # of trailing 0 bits in index
+    movd        mm_nbits, nbits                           ;   nbits --> MMX register
+    psllq       mm_put_buffer, mm_nbits                   ;   put_buffer <<= nbits;
+    inc         size                                      ;   ++size;
+    por         mm_put_buffer, mm_code                    ;   put_buffer |= code;
+    test        index, index
+    jnz         .BLOOP1                                   ; } while (index != 0);
+; Round 2
+; t points to the last used word, possibly below t_ if the previous index had 32 zero bits.
+.ELOOP1:                                                  ; .ELOOP1:
+    pmovmskb    size, xmm4                                ; size = 0;  size |= ((b4[i] >> 7) << i);
+    pmovmskb    index, xmm5                               ; index = 0;  index |= ((b5[i] >> 7) << i);
+    shl         size, 16                                  ; size <<= 16;
+    or          index, size                               ; index |= size;
+    not         index                                     ; index = ~index;
+    lea         nbits, [t + (1 + DCTSIZE2) * SIZEOF_WORD]
+                                                          ; nbits = t + 1 + 64;
+    and         nbits, -DCTSIZE2 * SIZEOF_WORD            ; nbits &= -128;  /* now points to &t_[64] */
+    sub         nbits, t                                  ; nbits -= t;
+    shr         nbits, 1                                  ; nbits >>= 1;  /* # of leading 0 bits in old index + 33 */
+    tzcnt       size, index                               ; size = # of trailing 0 bits in index
+    inc         size                                      ; ++size;
+    test        index, index                              ; if (index == 0)
+    jz          .ELOOP2                                   ;   goto .ELOOP2;
+; NOTE: size == 32 cannot happen, since the last element is always 0.
+    shr         index, sizeb                              ; index >>= size;
+    lea         size, [size + nbits - 33]                 ; size = size + nbits - 33;
+    lea         t, [t + size * SIZEOF_WORD]               ; t += size;
+    cmp         size, 16                                  ; if (size <= 16)
+    jle         .ERLOOP2                                  ;   goto .ERLOOP2;
+.BRLOOP2:                                                 ; do {
+    movzx       nbits, byte [actbl + c_derived_tbl.ehufsi + 0xf0]
+                                                          ;   nbits = actbl->ehufsi[0xf0];
+    sub         size, 16                                  ;   size -= 16;
+    movd        mm_code, dword [actbl + c_derived_tbl.ehufco + 0xf0 * 4]
+                                                          ;   code = actbl->ehufco[0xf0];
+    sub         free_bits, nbits                          ;   if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_BRLOOP2                             ;     insert code and flush put_buffer
+    movd        mm_nbits, nbits                           ;   else { nbits --> MMX register
+    psllq       mm_put_buffer, mm_nbits                   ;     put_buffer <<= nbits;
+    por         mm_put_buffer, mm_code                    ;     put_buffer |= code;
+    cmp         size, 16                                  ;     if (size <= 16)
+    jle        .ERLOOP2                                   ;       goto .ERLOOP2;
+    jmp        .BRLOOP2                                   ; } while (1);
 
-    pop         ebp
-    pop         edi
-    pop         esi
-;   pop         edx                     ; need not be preserved
-    pop         ecx
-    pop         ebx
-    mov         esp, ebp                ; esp <- aligned ebp
-    pop         esp                     ; esp <- original ebp
-    pop         ebp
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align      16
+.BLOOP2:                                                  ; do {  /* size = # of zero bits/elements to skip */
+    shr         index, sizeb                              ;   index >>= size;
+    lea         t, [t + size * SIZEOF_WORD]               ;   t += size;
+    cmp         size, 16                                  ;   if (size > 16)
+    jg          .BRLOOP2                                  ;     goto .BRLOOP2;
+.ERLOOP2:                                                 ; .ERLOOP2:
+    movsx       nbits, word [t]                           ;   nbits = *t;
+    add         size, size                                ;   size += size;
+    movd        mm_temp, nbits                            ;   temp = nbits;
+    movzx       nbits, byte [NBITS(nbits)]                ;   nbits = JPEG_NBITS(nbits);
+    movd        mm_nbits, nbits                           ;   nbits --> MMX register
+    lea         size, [size * 8 + nbits]                  ;   size = size * 8 + nbits;
+    movd        mm_code, dword [actbl + c_derived_tbl.ehufco + (size - 16) * 4]
+                                                          ;   code = actbl->ehufco[size-16];
+    movzx       size, byte [actbl + c_derived_tbl.ehufsi + (size - 16)]
+                                                          ;   size = actbl->ehufsi[size-16];
+    psllq       mm_code, mm_nbits                         ;   code <<= nbits;
+    pand        mm_temp, [MASK_BITS(nbits)]               ;   temp &= (1 << nbits) - 1;
+    lea         nbits, [nbits + size]                     ;   nbits += size;
+    por         mm_code, mm_temp                          ;   code |= temp;
+    xor         size, size                                ;   size = 0;  /* kill tzcnt input dependency */
+    sub         free_bits, nbits                          ;   if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_ERLOOP2                             ;     insert code, flush buffer, init size, goto .BLOOP2
+    tzcnt       size, index                               ;   size = # of trailing 0 bits in index
+    movd        mm_nbits, nbits                           ;   nbits --> MMX register
+    psllq       mm_put_buffer, mm_nbits                   ;   put_buffer <<= nbits;
+    inc         size                                      ;   ++size;
+    por         mm_put_buffer, mm_code                    ;   put_buffer |= code;
+    test        index, index
+    jnz         .BLOOP2                                   ; } while (index != 0);
+.ELOOP2:                                                  ; .ELOOP2:
+    mov         nbits, t                                  ; nbits = t;
+    lea         t, [t + SIZEOF_WORD]                      ; t = &t[1];
+    and         nbits, DCTSIZE2 * SIZEOF_WORD - 1         ; nbits &= 127;
+    and         t, -DCTSIZE2 * SIZEOF_WORD                ; t &= -128;  /* t = &t_[0]; */
+    cmp         nbits, (DCTSIZE2 - 2) * SIZEOF_WORD       ; if (nbits != 62 * 2)
+    je          .EFN                                      ; {
+    movd        mm_code, dword [actbl + c_derived_tbl.ehufco + 0]
+                                                          ;   code = actbl->ehufco[0];
+    movzx       nbits, byte [actbl + c_derived_tbl.ehufsi + 0]
+                                                          ;   nbits = actbl->ehufsi[0];
+    sub         free_bits, nbits                          ;   if ((free_bits -= nbits) <= 0)
+    jg          .EFN_SKIP_EMIT_CODE                       ;   {
+    EMIT_QWORD  size, sizeb, sizeh, , , , , , .EFN        ;     insert code, flush put_buffer
+    align       16
+.EFN_SKIP_EMIT_CODE:                                      ;   } else {
+    movd        mm_nbits, nbits                           ;     nbits --> MMX register
+    psllq       mm_put_buffer, mm_nbits                   ;     put_buffer <<= nbits;
+    por         mm_put_buffer, mm_code                    ;     put_buffer |= code;
+.EFN:                                                     ; } }
+%define frame  esp
+    mov         frame, [t + save_frame]
+%define state  ecx
+    mov         state, [frame + arg_state]
+    movq        [state + working_state.cur.put_buffer.simd], mm_put_buffer
+                                                          ; state->cur.put_buffer.simd = put_buffer;
+    emms
+    mov         [state + working_state.cur.free_bits], free_bits
+                                                          ; state->cur.free_bits = free_bits;
+    POP         edi
+    POP         esi
+    POP         ebp
+    POP         ebx
     ret
 
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+.EMIT_BRLOOP1:
+    EMIT_QWORD  emit_temp, emit_tempb, emit_temph, , , , , , \
+      .ERLOOP1
+
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+.EMIT_ERLOOP1:
+    EMIT_QWORD  size, sizeb, sizeh, \
+      { xor     size, size }, \
+      { tzcnt   size, index }, \
+      { inc     size }, \
+      { test    index, index }, \
+      { jnz     .BLOOP1 }, \
+      .ELOOP1
+
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+.EMIT_BRLOOP2:
+    EMIT_QWORD  emit_temp, emit_tempb, emit_temph, , , , \
+      { cmp     size, 16 }, \
+      { jle     .ERLOOP2 }, \
+      .BRLOOP2
+
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+.EMIT_ERLOOP2:
+    EMIT_QWORD  size, sizeb, sizeh, \
+      { xor     size, size }, \
+      { tzcnt   size, index }, \
+      { inc     size }, \
+      { test    index, index }, \
+      { jnz     .BLOOP2 }, \
+      .ELOOP2
+
 ; For some reason, the OS X linker does not honor the request to align the
 ; segment unless we do this.
     align       32
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcphuff-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcphuff-sse2.asm
index 25c63c7..c26b48a4 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcphuff-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcphuff-sse2.asm
@@ -15,8 +15,6 @@
 ;
 ; This file contains an SSE2 implementation of data preparation for progressive
 ; Huffman encoding.  See jcphuff.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -329,6 +327,8 @@
     add         LUT, 16*SIZEOF_INT
     dec         K
     jnz         .BLOOP16
+    test        LEN, 15
+    je          .PADDING
 .ELOOP16:
     mov         LENEND, LEN
     and         LENEND, 7
@@ -523,6 +523,8 @@
     add         KK, 2
     dec         K
     jnz         .BLOOPR16
+    test        LEN, 15
+    je          .PADDINGR
 .ELOOPR16:
     mov         LENEND, LEN
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcsample-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcsample-avx2.asm
index 5bcdefd..0a20802 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcsample-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcsample-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcsample-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jcsample-mmx.asm
index faf4234..2c223ee 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcsample-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcsample-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jcsample-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jcsample-sse2.asm
index b10fa83..4fea60d 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jcsample-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jcsample-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-avx2.asm
index 46de9b9..015be04 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -348,7 +346,7 @@
     vmovd       eax, xmmA
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi], ax
+    mov         word [edi], ax
     add         edi, byte SIZEOF_WORD
     sub         ecx, byte SIZEOF_WORD
     shr         eax, 16
@@ -357,7 +355,7 @@
     ; space.
     test        ecx, ecx
     jz          short .nextrow
-    mov         BYTE [edi], al
+    mov         byte [edi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-mmx.asm
index cd2cb3f..5813cfc 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -280,7 +278,7 @@
     movd        eax, mmA
     cmp         ecx, byte SIZEOF_DWORD
     jb          short .column_st2
-    mov         DWORD [edi+0*SIZEOF_DWORD], eax
+    mov         dword [edi+0*SIZEOF_DWORD], eax
     psrlq       mmA, DWORD_BIT
     movd        eax, mmA
     sub         ecx, byte SIZEOF_DWORD
@@ -288,14 +286,14 @@
 .column_st2:
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi+0*SIZEOF_WORD], ax
+    mov         word [edi+0*SIZEOF_WORD], ax
     shr         eax, WORD_BIT
     sub         ecx, byte SIZEOF_WORD
     add         edi, byte SIZEOF_WORD
 .column_st1:
     cmp         ecx, byte SIZEOF_BYTE
     jb          short .nextrow
-    mov         BYTE [edi+0*SIZEOF_BYTE], al
+    mov         byte [edi+0*SIZEOF_BYTE], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
@@ -367,7 +365,7 @@
 .column_st4:
     cmp         ecx, byte SIZEOF_MMWORD/8
     jb          short .nextrow
-    movd        DWORD [edi+0*SIZEOF_DWORD], mmA
+    movd        dword [edi+0*SIZEOF_DWORD], mmA
 
 %endif  ; RGB_PIXELSIZE ; ---------------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-sse2.asm
index 0fcb006..d5572b3 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolext-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -320,7 +318,7 @@
     movd        eax, xmmA
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi], ax
+    mov         word [edi], ax
     add         edi, byte SIZEOF_WORD
     sub         ecx, byte SIZEOF_WORD
     shr         eax, 16
@@ -329,7 +327,7 @@
     ; space.
     test        ecx, ecx
     jz          short .nextrow
-    mov         BYTE [edi], al
+    mov         byte [edi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-avx2.asm
index d2f86e6..e05b60d 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-mmx.asm
index 8f5a3b3..fb7e7bc 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-sse2.asm
index ae553db..b736255 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdcolor-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdcolor-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-avx2.asm
index 1731844..711e679 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-mmx.asm
index 607bf39..6e8311d 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-sse2.asm
index ddb1d5e..e32f90a 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmerge-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmerge-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-avx2.asm
index cde4865..e35f728 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -354,7 +352,7 @@
     vmovd       eax, xmmA
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi], ax
+    mov         word [edi], ax
     add         edi, byte SIZEOF_WORD
     sub         ecx, byte SIZEOF_WORD
     shr         eax, 16
@@ -363,7 +361,7 @@
     ; space.
     test        ecx, ecx
     jz          short .endcolumn
-    mov         BYTE [edi], al
+    mov         byte [edi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-mmx.asm
index 4b9e35d..eb3e36b 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -283,7 +281,7 @@
     movd        eax, mmA
     cmp         ecx, byte SIZEOF_DWORD
     jb          short .column_st2
-    mov         DWORD [edi+0*SIZEOF_DWORD], eax
+    mov         dword [edi+0*SIZEOF_DWORD], eax
     psrlq       mmA, DWORD_BIT
     movd        eax, mmA
     sub         ecx, byte SIZEOF_DWORD
@@ -291,14 +289,14 @@
 .column_st2:
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi+0*SIZEOF_WORD], ax
+    mov         word [edi+0*SIZEOF_WORD], ax
     shr         eax, WORD_BIT
     sub         ecx, byte SIZEOF_WORD
     add         edi, byte SIZEOF_WORD
 .column_st1:
     cmp         ecx, byte SIZEOF_BYTE
     jb          short .endcolumn
-    mov         BYTE [edi+0*SIZEOF_BYTE], al
+    mov         byte [edi+0*SIZEOF_BYTE], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
@@ -373,7 +371,7 @@
 .column_st4:
     cmp         ecx, byte SIZEOF_MMWORD/8
     jb          short .endcolumn
-    movd        DWORD [edi+0*SIZEOF_DWORD], mmA
+    movd        dword [edi+0*SIZEOF_DWORD], mmA
 
 %endif  ; RGB_PIXELSIZE ; ---------------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-sse2.asm
index ac4697e..c113dc4 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdmrgext-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -325,7 +323,7 @@
     movd        eax, xmmA
     cmp         ecx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [edi], ax
+    mov         word [edi], ax
     add         edi, byte SIZEOF_WORD
     sub         ecx, byte SIZEOF_WORD
     shr         eax, 16
@@ -334,7 +332,7 @@
     ; space.
     test        ecx, ecx
     jz          short .endcolumn
-    mov         BYTE [edi], al
+    mov         byte [edi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdsample-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdsample-avx2.asm
index 61ce511..a800c35 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdsample-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdsample-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdsample-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jdsample-mmx.asm
index 1f810fa..12c49f0 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdsample-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdsample-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jdsample-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jdsample-sse2.asm
index f0da626..4e28d2f 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jdsample-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jdsample-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-3dn.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-3dn.asm
index 1d45865..322ab16 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-3dn.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-3dn.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the forward DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-sse.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-sse.asm
index 1faf835..86952c6 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-sse.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctflt-sse.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the forward DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-mmx.asm
index 0271901..80645a5 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-mmx.asm
@@ -18,8 +18,6 @@
 ; the forward DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-sse2.asm
index f09dadd..446fa7a 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctfst-sse2.asm
@@ -18,8 +18,6 @@
 ; the forward DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-avx2.asm
index ae258ee..23cf733 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-avx2.asm
@@ -2,7 +2,7 @@
 ; jfdctint.asm - accurate integer FDCT (AVX2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, 2018, D. R. Commander.
+; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; forward DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -105,7 +103,7 @@
 %endmacro
 
 ; --------------------------------------------------------------------------
-; In-place 8x8x16-bit slow integer forward DCT using AVX2 instructions
+; In-place 8x8x16-bit accurate integer forward DCT using AVX2 instructions
 ; %1-%4: Input/output registers
 ; %5-%8: Temp registers
 ; %9:    Pass (1 or 2)
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-mmx.asm
index c6bd959..34a43b9 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-mmx.asm
@@ -2,7 +2,7 @@
 ; jfdctint.asm - accurate integer FDCT (MMX)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2016, D. R. Commander.
+; Copyright (C) 2016, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; forward DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-sse2.asm
index d67dcc1..6f8e18c 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jfdctint-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jfdctint-sse2.asm
@@ -2,7 +2,7 @@
 ; jfdctint.asm - accurate integer FDCT (SSE2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2016, D. R. Commander.
+; Copyright (C) 2016, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; forward DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-3dn.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-3dn.asm
index 73aa18d..8795191 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-3dn.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-3dn.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the inverse DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jidctflt.c; see the jidctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -92,23 +90,23 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_FLOAT_3DNOW
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     pushpic     ebx                     ; save GOT address
-    mov         ebx, DWORD [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
-    mov         eax, DWORD [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
-    or          ebx, DWORD [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
-    or          ebx, DWORD [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
+    mov         ebx, dword [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
+    or          ebx, dword [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
+    or          ebx, dword [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
     or          eax, ebx
     poppic      ebx                     ; restore GOT address
     jnz         short .columnDCT
 
     ; -- AC terms all zero
 
-    movd        mm0, DWORD [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
+    movd        mm0, dword [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
 
     punpcklwd   mm0, mm0
     psrad       mm0, (DWORD_BIT-WORD_BIT)
@@ -135,10 +133,10 @@
 
     ; -- Even part
 
-    movd        mm0, DWORD [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
-    movd        mm1, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
-    movd        mm2, DWORD [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
-    movd        mm3, DWORD [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
+    movd        mm0, dword [DWBLOCK(0,0,esi,SIZEOF_JCOEF)]
+    movd        mm1, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    movd        mm2, dword [DWBLOCK(4,0,esi,SIZEOF_JCOEF)]
+    movd        mm3, dword [DWBLOCK(6,0,esi,SIZEOF_JCOEF)]
 
     punpcklwd   mm0, mm0
     punpcklwd   mm1, mm1
@@ -182,10 +180,10 @@
 
     ; -- Odd part
 
-    movd        mm2, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    movd        mm3, DWORD [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
-    movd        mm5, DWORD [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
-    movd        mm1, DWORD [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
+    movd        mm2, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    movd        mm3, dword [DWBLOCK(3,0,esi,SIZEOF_JCOEF)]
+    movd        mm5, dword [DWBLOCK(5,0,esi,SIZEOF_JCOEF)]
+    movd        mm1, dword [DWBLOCK(7,0,esi,SIZEOF_JCOEF)]
 
     punpcklwd   mm2, mm2
     punpcklwd   mm3, mm3
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse.asm
index 386650f..b27ecfd 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the inverse DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jidctflt.c; see the jidctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -102,8 +100,8 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movq        mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse2.asm
index 9de7139..c646eae 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctflt-sse2.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the inverse DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jidctflt.c; see the jidctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -102,8 +100,8 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movq        xmm1, XMM_MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctfst-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctfst-mmx.asm
index d3e8a5d..24622d4 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctfst-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctfst-mmx.asm
@@ -18,8 +18,6 @@
 ; the inverse DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jidctfst.c; see the jidctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -123,8 +121,8 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_IFAST_MMX
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     movq        mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctfst-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctfst-sse2.asm
index 83bc414..19704ff 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctfst-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctfst-sse2.asm
@@ -18,8 +18,6 @@
 ; the inverse DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jidctfst.c; see the jidctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -118,8 +116,8 @@
     mov         esi, JCOEFPTR [coef_block(eax)]  ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_IFAST_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctint-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctint-avx2.asm
index b3b7b14..199c7df 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctint-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctint-avx2.asm
@@ -2,7 +2,7 @@
 ; jidctint.asm - accurate integer IDCT (AVX2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, 2018, D. R. Commander.
+; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; inverse DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jidctint.c; see the jidctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -115,7 +113,7 @@
 %endmacro
 
 ; --------------------------------------------------------------------------
-; In-place 8x8x16-bit slow integer inverse DCT using AVX2 instructions
+; In-place 8x8x16-bit accurate integer inverse DCT using AVX2 instructions
 ; %1-%4:  Input/output registers
 ; %5-%12: Temp registers
 ; %9:     Pass (1 or 2)
@@ -320,8 +318,8 @@
     mov         esi, JCOEFPTR [coef_block(eax)]  ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_ISLOW_AVX2
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctint-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctint-mmx.asm
index 6ca6d06..f15c8d3 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctint-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctint-mmx.asm
@@ -2,7 +2,7 @@
 ; jidctint.asm - accurate integer IDCT (MMX)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2016, D. R. Commander.
+; Copyright (C) 2016, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; inverse DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jidctint.c; see the jidctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -136,8 +134,8 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_ISLOW_MMX
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     movq        mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctint-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctint-sse2.asm
index a6bd00a..43e3201 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctint-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctint-sse2.asm
@@ -2,7 +2,7 @@
 ; jidctint.asm - accurate integer IDCT (SSE2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2016, D. R. Commander.
+; Copyright (C) 2016, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; inverse DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jidctint.c; see the jidctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -131,8 +129,8 @@
     mov         esi, JCOEFPTR [coef_block(eax)]  ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_ISLOW_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctred-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctred-mmx.asm
index 336ee3b..e2307e1 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctred-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctred-mmx.asm
@@ -18,8 +18,6 @@
 ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
 ; The following code is based directly on the IJG's original jidctred.c;
 ; see the jidctred.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -144,8 +142,8 @@
     alignx      16, 7
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_4X4_MMX
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     movq        mm0, MMWORD [MMBLOCK(1,0,esi,SIZEOF_JCOEF)]
@@ -464,16 +462,16 @@
 
     mov         edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
     mov         esi, JSAMPROW [edi+2*SIZEOF_JSAMPROW]
-    movd        DWORD [edx+eax*SIZEOF_JSAMPLE], mm1
-    movd        DWORD [esi+eax*SIZEOF_JSAMPLE], mm0
+    movd        dword [edx+eax*SIZEOF_JSAMPLE], mm1
+    movd        dword [esi+eax*SIZEOF_JSAMPLE], mm0
 
     psrlq       mm1, 4*BYTE_BIT
     psrlq       mm0, 4*BYTE_BIT
 
     mov         edx, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
     mov         esi, JSAMPROW [edi+3*SIZEOF_JSAMPROW]
-    movd        DWORD [edx+eax*SIZEOF_JSAMPLE], mm1
-    movd        DWORD [esi+eax*SIZEOF_JSAMPLE], mm0
+    movd        dword [edx+eax*SIZEOF_JSAMPLE], mm1
+    movd        dword [esi+eax*SIZEOF_JSAMPLE], mm0
 
     emms                                ; empty MMX state
 
@@ -688,8 +686,8 @@
 
     mov         edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
     mov         esi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
-    mov         WORD [edx+eax*SIZEOF_JSAMPLE], bx
-    mov         WORD [esi+eax*SIZEOF_JSAMPLE], cx
+    mov         word [edx+eax*SIZEOF_JSAMPLE], bx
+    mov         word [esi+eax*SIZEOF_JSAMPLE], cx
 
     emms                                ; empty MMX state
 
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jidctred-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jidctred-sse2.asm
index 97838ba..6e56494 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jidctred-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jidctred-sse2.asm
@@ -18,8 +18,6 @@
 ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
 ; The following code is based directly on the IJG's original jidctred.c;
 ; see the jidctred.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -139,8 +137,8 @@
     mov         esi, JCOEFPTR [coef_block(eax)]  ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_4X4_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_JCOEF)]
@@ -578,8 +576,8 @@
 
     mov         edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW]
     mov         esi, JSAMPROW [edi+1*SIZEOF_JSAMPROW]
-    mov         WORD [edx+eax*SIZEOF_JSAMPLE], bx
-    mov         WORD [esi+eax*SIZEOF_JSAMPLE], cx
+    mov         word [edx+eax*SIZEOF_JSAMPLE], bx
+    mov         word [esi+eax*SIZEOF_JSAMPLE], cx
 
     pop         edi
     pop         esi
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquant-3dn.asm b/src/third_party/libjpeg-turbo/simd/i386/jquant-3dn.asm
index 1767f44..5cb60ca 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquant-3dn.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquant-3dn.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquant-mmx.asm b/src/third_party/libjpeg-turbo/simd/i386/jquant-mmx.asm
index 98932db..61305c6 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquant-mmx.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquant-mmx.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquant-sse.asm b/src/third_party/libjpeg-turbo/simd/i386/jquant-sse.asm
index cc244c4..218adc9 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquant-sse.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquant-sse.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquantf-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jquantf-sse2.asm
index 8d1201c..a881ab5 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquantf-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquantf-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquanti-avx2.asm b/src/third_party/libjpeg-turbo/simd/i386/jquanti-avx2.asm
index ea8e1a1..5ed6bec 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquanti-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquanti-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jquanti-sse2.asm b/src/third_party/libjpeg-turbo/simd/i386/jquanti-sse2.asm
index 2a69494..0a50940 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jquanti-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jquanti-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/i386/jsimdcpu.asm b/src/third_party/libjpeg-turbo/simd/i386/jsimdcpu.asm
index 50a0d51..ddcafa9 100644
--- a/src/third_party/libjpeg-turbo/simd/i386/jsimdcpu.asm
+++ b/src/third_party/libjpeg-turbo/simd/i386/jsimdcpu.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -51,29 +49,14 @@
     xor         eax, edx
     jz          near .return            ; CPUID is not supported
 
-    ; Check for MMX instruction support
+    ; Check whether CPUID leaf 07H is supported
+    ; (leaf 07H is used to check for AVX2 instruction support)
     xor         eax, eax
     cpuid
     test        eax, eax
     jz          near .return
-
-    xor         eax, eax
-    inc         eax
-    cpuid
-    mov         eax, edx                ; eax = Standard feature flags
-
-    test        eax, 1<<23              ; bit23:MMX
-    jz          short .no_mmx
-    or          edi, byte JSIMD_MMX
-.no_mmx:
-    test        eax, 1<<25              ; bit25:SSE
-    jz          short .no_sse
-    or          edi, byte JSIMD_SSE
-.no_sse:
-    test        eax, 1<<26              ; bit26:SSE2
-    jz          short .no_sse2
-    or          edi, byte JSIMD_SSE2
-.no_sse2:
+    cmp         eax, 7
+    jl          short .no_avx2          ; Maximum leaf < 07H
 
     ; Check for AVX2 instruction support
     mov         eax, 7
@@ -94,13 +77,34 @@
 
     xor         ecx, ecx
     xgetbv
-    test        eax, 6                  ; O/S does not manage XMM/YMM state
+    and         eax, 6
+    cmp         eax, 6                  ; O/S does not manage XMM/YMM state
                                         ; using XSAVE
-    jz          short .no_avx2
+    jnz         short .no_avx2
 
     or          edi, JSIMD_AVX2
 .no_avx2:
 
+    ; Check CPUID leaf 01H for MMX, SSE, and SSE2 support
+    xor         eax, eax
+    inc         eax
+    cpuid
+    mov         eax, edx                ; eax = Standard feature flags
+
+    ; Check for MMX instruction support
+    test        eax, 1<<23              ; bit23:MMX
+    jz          short .no_mmx
+    or          edi, byte JSIMD_MMX
+.no_mmx:
+    test        eax, 1<<25              ; bit25:SSE
+    jz          short .no_sse
+    or          edi, byte JSIMD_SSE
+.no_sse:
+    test        eax, 1<<26              ; bit26:SSE2
+    jz          short .no_sse2
+    or          edi, byte JSIMD_SSE2
+.no_sse2:
+
     ; Check for 3DNow! instruction support
     mov         eax, 0x80000000
     cpuid
diff --git a/src/third_party/libjpeg-turbo/simd/jsimd.h b/src/third_party/libjpeg-turbo/simd/jsimd.h
index a9fc812..64747c6 100644
--- a/src/third_party/libjpeg-turbo/simd/jsimd.h
+++ b/src/third_party/libjpeg-turbo/simd/jsimd.h
@@ -2,11 +2,12 @@
  * simd/jsimd.h
  *
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2011, 2014-2016, 2018, D. R. Commander.
+ * Copyright (C) 2011, 2014-2016, 2018, 2020, D. R. Commander.
  * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
  * Copyright (C) 2014, Linaro Limited.
  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
+ * Copyright (C) 2016-2018, Loongson Technology Corporation Limited, BeiJing.
+ * Copyright (C) 2020, Arm Limited.
  *
  * Based on the x86 SIMD extension for IJG JPEG library,
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -121,6 +122,8 @@
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
 
+#ifndef NEON_INTRINSICS
+
 EXTERN(void) jsimd_extrgb_ycc_convert_neon_slowld3
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
@@ -128,6 +131,8 @@
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
 
+#endif
+
 EXTERN(void) jsimd_rgb_ycc_convert_dspr2
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
@@ -263,6 +268,28 @@
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
 
+EXTERN(void) jsimd_rgb_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extrgb_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extrgbx_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extbgr_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extbgrx_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extxbgr_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extxrgb_gray_convert_neon
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+
 EXTERN(void) jsimd_rgb_gray_convert_dspr2
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
@@ -285,6 +312,28 @@
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
 
+EXTERN(void) jsimd_rgb_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extrgb_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extrgbx_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extbgr_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extbgrx_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extxbgr_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+EXTERN(void) jsimd_extxrgb_gray_convert_mmi
+  (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+   JDIMENSION output_row, int num_rows);
+
 EXTERN(void) jsimd_rgb_gray_convert_altivec
   (JDIMENSION img_width, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    JDIMENSION output_row, int num_rows);
@@ -401,6 +450,8 @@
   (JDIMENSION out_width, JSAMPIMAGE input_buf, JDIMENSION input_row,
    JSAMPARRAY output_buf, int num_rows);
 
+#ifndef NEON_INTRINSICS
+
 EXTERN(void) jsimd_ycc_extrgb_convert_neon_slowst3
   (JDIMENSION out_width, JSAMPIMAGE input_buf, JDIMENSION input_row,
    JSAMPARRAY output_buf, int num_rows);
@@ -408,6 +459,8 @@
   (JDIMENSION out_width, JSAMPIMAGE input_buf, JDIMENSION input_row,
    JSAMPARRAY output_buf, int num_rows);
 
+#endif
+
 EXTERN(void) jsimd_ycc_rgb_convert_dspr2
   (JDIMENSION out_width, JSAMPIMAGE input_buf, JDIMENSION input_row,
    JSAMPARRAY output_buf, int num_rows);
@@ -562,6 +615,13 @@
   (int max_v_samp_factor, JDIMENSION output_width, JSAMPARRAY input_data,
    JSAMPARRAY *output_data_ptr);
 
+EXTERN(void) jsimd_h2v1_upsample_neon
+  (int max_v_samp_factor, JDIMENSION output_width, JSAMPARRAY input_data,
+   JSAMPARRAY *output_data_ptr);
+EXTERN(void) jsimd_h2v2_upsample_neon
+  (int max_v_samp_factor, JDIMENSION output_width, JSAMPARRAY input_data,
+   JSAMPARRAY *output_data_ptr);
+
 EXTERN(void) jsimd_h2v1_upsample_dspr2
   (int max_v_samp_factor, JDIMENSION output_width, JSAMPARRAY input_data,
    JSAMPARRAY *output_data_ptr);
@@ -608,6 +668,12 @@
 EXTERN(void) jsimd_h2v1_fancy_upsample_neon
   (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
    JSAMPARRAY *output_data_ptr);
+EXTERN(void) jsimd_h2v2_fancy_upsample_neon
+  (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
+   JSAMPARRAY *output_data_ptr);
+EXTERN(void) jsimd_h1v2_fancy_upsample_neon
+  (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
+   JSAMPARRAY *output_data_ptr);
 
 EXTERN(void) jsimd_h2v1_fancy_upsample_dspr2
   (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
@@ -616,6 +682,9 @@
   (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
    JSAMPARRAY *output_data_ptr);
 
+EXTERN(void) jsimd_h2v1_fancy_upsample_mmi
+  (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
+   JSAMPARRAY *output_data_ptr);
 EXTERN(void) jsimd_h2v2_fancy_upsample_mmi
   (int max_v_samp_factor, JDIMENSION downsampled_width, JSAMPARRAY input_data,
    JSAMPARRAY *output_data_ptr);
@@ -762,6 +831,50 @@
   (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    JSAMPARRAY output_buf);
 
+EXTERN(void) jsimd_h2v1_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+
+EXTERN(void) jsimd_h2v2_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_neon
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+
 EXTERN(void) jsimd_h2v1_merged_upsample_dspr2
   (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    JSAMPARRAY output_buf, JSAMPLE *range);
@@ -806,6 +919,50 @@
   (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    JSAMPARRAY output_buf, JSAMPLE *range);
 
+EXTERN(void) jsimd_h2v1_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extrgb_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extrgbx_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extbgr_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extbgrx_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extxbgr_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v1_extxrgb_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+
+EXTERN(void) jsimd_h2v2_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extrgb_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extrgbx_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extbgr_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extbgrx_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extxbgr_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+EXTERN(void) jsimd_h2v2_extxrgb_merged_upsample_mmi
+  (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+   JSAMPARRAY output_buf);
+
 EXTERN(void) jsimd_h2v1_merged_upsample_altivec
   (JDIMENSION output_width, JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    JSAMPARRAY output_buf);
@@ -882,7 +1039,7 @@
 EXTERN(void) jsimd_convsamp_float_dspr2
   (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT *workspace);
 
-/* Slow Integer Forward DCT */
+/* Accurate Integer Forward DCT */
 EXTERN(void) jsimd_fdct_islow_mmx(DCTELEM *data);
 
 extern const int jconst_fdct_islow_sse2[];
@@ -909,6 +1066,8 @@
 
 EXTERN(void) jsimd_fdct_ifast_dspr2(DCTELEM *data);
 
+EXTERN(void) jsimd_fdct_ifast_mmi(DCTELEM *data);
+
 EXTERN(void) jsimd_fdct_ifast_altivec(DCTELEM *data);
 
 /* Floating Point Forward DCT */
@@ -989,7 +1148,7 @@
 EXTERN(void) jsimd_idct_12x12_pass2_dspr2
   (int *workspace, int *output);
 
-/* Slow Integer Inverse DCT */
+/* Accurate Integer Inverse DCT */
 EXTERN(void) jsimd_idct_islow_mmx
   (void *dct_table, JCOEFPTR coef_block, JSAMPARRAY output_buf,
    JDIMENSION output_col);
@@ -1040,6 +1199,10 @@
   (DCTELEM *wsptr, JSAMPARRAY output_buf, JDIMENSION output_col,
    const int *idct_coefs);
 
+EXTERN(void) jsimd_idct_ifast_mmi
+  (void *dct_table, JCOEFPTR coef_block, JSAMPARRAY output_buf,
+   JDIMENSION output_col);
+
 EXTERN(void) jsimd_idct_ifast_altivec
   (void *dct_table, JCOEFPTR coef_block, JSAMPARRAY output_buf,
    JDIMENSION output_col);
@@ -1069,15 +1232,27 @@
   (void *state, JOCTET *buffer, JCOEFPTR block, int last_dc_val,
    c_derived_tbl *dctbl, c_derived_tbl *actbl);
 
+#ifndef NEON_INTRINSICS
+
 EXTERN(JOCTET *) jsimd_huff_encode_one_block_neon_slowtbl
   (void *state, JOCTET *buffer, JCOEFPTR block, int last_dc_val,
    c_derived_tbl *dctbl, c_derived_tbl *actbl);
 
+#endif
+
 /* Progressive Huffman encoding */
 EXTERN(void) jsimd_encode_mcu_AC_first_prepare_sse2
   (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
    JCOEF *values, size_t *zerobits);
 
+EXTERN(void) jsimd_encode_mcu_AC_first_prepare_neon
+  (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
+   JCOEF *values, size_t *zerobits);
+
 EXTERN(int) jsimd_encode_mcu_AC_refine_prepare_sse2
   (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
    JCOEF *absvalues, size_t *bits);
+
+EXTERN(int) jsimd_encode_mcu_AC_refine_prepare_neon
+  (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al,
+   JCOEF *absvalues, size_t *bits);
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jccolext-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jccolext-mmi.c
deleted file mode 100644
index e1c4e69..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jccolext-mmi.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jccolor-mmi.c */
-
-
-#if RGB_RED == 0
-#define mmA  mm0
-#define mmB  mm1
-#elif RGB_GREEN == 0
-#define mmA  mm2
-#define mmB  mm3
-#elif RGB_BLUE == 0
-#define mmA  mm4
-#define mmB  mm5
-#else
-#define mmA  mm6
-#define mmB  mm7
-#endif
-
-#if RGB_RED == 1
-#define mmC  mm0
-#define mmD  mm1
-#elif RGB_GREEN == 1
-#define mmC  mm2
-#define mmD  mm3
-#elif RGB_BLUE == 1
-#define mmC  mm4
-#define mmD  mm5
-#else
-#define mmC  mm6
-#define mmD  mm7
-#endif
-
-#if RGB_RED == 2
-#define mmE  mm0
-#define mmF  mm1
-#elif RGB_GREEN == 2
-#define mmE  mm2
-#define mmF  mm3
-#elif RGB_BLUE == 2
-#define mmE  mm4
-#define mmF  mm5
-#else
-#define mmE  mm6
-#define mmF  mm7
-#endif
-
-#if RGB_RED == 3
-#define mmG  mm0
-#define mmH  mm1
-#elif RGB_GREEN == 3
-#define mmG  mm2
-#define mmH  mm3
-#elif RGB_BLUE == 3
-#define mmG  mm4
-#define mmH  mm5
-#else
-#define mmG  mm6
-#define mmH  mm7
-#endif
-
-
-void jsimd_rgb_ycc_convert_mmi(JDIMENSION image_width, JSAMPARRAY input_buf,
-                               JSAMPIMAGE output_buf, JDIMENSION output_row,
-                               int num_rows)
-{
-  JSAMPROW inptr, outptr0, outptr1, outptr2;
-  int num_cols, col;
-  __m64 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
-  __m64 wk[7];
-  __m64 Y_BG, Cb_RG, Cr_BG;
-
-  while (--num_rows >= 0) {
-    inptr = *input_buf++;
-    outptr0 = output_buf[0][output_row];
-    outptr1 = output_buf[1][output_row];
-    outptr2 = output_buf[2][output_row];
-    output_row++;
-
-    for (num_cols = image_width; num_cols > 0; num_cols -= 8,
-         outptr0 += 8, outptr1 += 8, outptr2 += 8) {
-
-#if RGB_PIXELSIZE == 3
-
-      if (num_cols < 8) {
-        col = num_cols * 3;
-        asm(".set noreorder\r\n"
-
-            "li     $8, 1\r\n"
-            "move   $9, %3\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 1f\r\n"
-            "nop    \r\n"
-            "subu   $9, $9, 1\r\n"
-            "xor    $12, $12, $12\r\n"
-            "move   $13, %5\r\n"
-            "dadd   $13, $13, $9\r\n"
-            "lbu    $12, 0($13)\r\n"
-
-            "1:     \r\n"
-            "li     $8, 2\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 2f\r\n"
-            "nop    \r\n"
-            "subu   $9, $9, 2\r\n"
-            "xor    $11, $11, $11\r\n"
-            "move   $13, %5\r\n"
-            "dadd   $13, $13, $9\r\n"
-            "lhu    $11, 0($13)\r\n"
-            "sll    $12, $12, 16\r\n"
-            "or     $12, $12, $11\r\n"
-
-            "2:     \r\n"
-            "dmtc1  $12, %0\r\n"
-            "li     $8, 4\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 3f\r\n"
-            "nop    \r\n"
-            "subu   $9, $9, 4\r\n"
-            "move   $13, %5\r\n"
-            "dadd   $13, $13, $9\r\n"
-            "lwu    $14, 0($13)\r\n"
-            "dmtc1  $14, %1\r\n"
-            "dsll32 $12, $12, 0\r\n"
-            "or     $12, $12, $14\r\n"
-            "dmtc1  $12, %0\r\n"
-
-            "3:     \r\n"
-            "li     $8, 8\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 4f\r\n"
-            "nop    \r\n"
-            "mov.s  %1, %0\r\n"
-            "ldc1   %0, 0(%5)\r\n"
-            "li     $9, 8\r\n"
-            "j      5f\r\n"
-            "nop    \r\n"
-
-            "4:     \r\n"
-            "li     $8, 16\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 5f\r\n"
-            "nop    \r\n"
-            "mov.s  %2, %0\r\n"
-            "ldc1   %0, 0(%5)\r\n"
-            "ldc1   %1, 8(%5)\r\n"
-
-            "5:     \r\n"
-            "nop    \r\n"
-            ".set reorder\r\n"
-
-            : "=f" (mmA), "=f" (mmG), "=f" (mmF)
-            : "r" (col), "r" (num_rows), "r" (inptr)
-            : "$f0", "$f2", "$f4", "$8", "$9", "$10", "$11", "$12", "$13",
-              "$14", "memory"
-           );
-      } else {
-        mmA = _mm_load_si64((__m64 *)&inptr[0]);
-        mmG = _mm_load_si64((__m64 *)&inptr[8]);
-        mmF = _mm_load_si64((__m64 *)&inptr[16]);
-        inptr += RGB_PIXELSIZE * 8;
-      }
-      mmD = mmA;
-      mmA = _mm_slli_si64(mmA, 4 * BYTE_BIT);
-      mmD = _mm_srli_si64(mmD, 4 * BYTE_BIT);
-
-      mmA = _mm_unpackhi_pi8(mmA, mmG);
-      mmG = _mm_slli_si64(mmG, 4 * BYTE_BIT);
-
-      mmD = _mm_unpacklo_pi8(mmD, mmF);
-      mmG = _mm_unpackhi_pi8(mmG, mmF);
-
-      mmE = mmA;
-      mmA = _mm_slli_si64(mmA, 4 * BYTE_BIT);
-      mmE = _mm_srli_si64(mmE, 4 * BYTE_BIT);
-
-      mmA = _mm_unpackhi_pi8(mmA, mmD);
-      mmD = _mm_slli_si64(mmD, 4 * BYTE_BIT);
-
-      mmE = _mm_unpacklo_pi8(mmE, mmG);
-      mmD = _mm_unpackhi_pi8(mmD, mmG);
-      mmC = mmA;
-      mmA = _mm_loadlo_pi8_f(mmA);
-      mmC = _mm_loadhi_pi8_f(mmC);
-
-      mmB = mmE;
-      mmE = _mm_loadlo_pi8_f(mmE);
-      mmB = _mm_loadhi_pi8_f(mmB);
-
-      mmF = mmD;
-      mmD = _mm_loadlo_pi8_f(mmD);
-      mmF = _mm_loadhi_pi8_f(mmF);
-
-#else  /* RGB_PIXELSIZE == 4 */
-
-      if (num_cols < 8) {
-        col = num_cols;
-        asm(".set noreorder\r\n"
-
-            "li     $8, 1\r\n"
-            "move   $9, %4\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 1f\r\n"
-            "nop    \r\n"
-            "subu   $9, $9, 1\r\n"
-            "dsll   $11, $9, 2\r\n"
-            "move   $13, %5\r\n"
-            "daddu  $13, $13, $11\r\n"
-            "lwc1   %0, 0($13)\r\n"
-
-            "1:     \r\n"
-            "li     $8, 2\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 2f\r\n"
-            "nop    \r\n"
-            "subu   $9, $9, 2\r\n"
-            "dsll   $11, $9, 2\r\n"
-            "move   $13, %5\r\n"
-            "daddu  $13, $13, $11\r\n"
-            "mov.s  %1, %0\r\n"
-            "ldc1   %0, 0($13)\r\n"
-
-            "2:     \r\n"
-            "li     $8, 4\r\n"
-            "and    $10, $9, $8\r\n"
-            "beqz   $10, 3f\r\n"
-            "nop    \r\n"
-            "mov.s  %2, %0\r\n"
-            "mov.s  %3, %1\r\n"
-            "ldc1   %0, 0(%5)\r\n"
-            "ldc1   %1, 8(%5)\r\n"
-
-            "3:     \r\n"
-            "nop    \r\n"
-            ".set reorder\r\n"
-
-            : "=f" (mmA), "=f" (mmF), "=f" (mmD), "=f" (mmC)
-            : "r" (col), "r" (inptr)
-            : "$f0", "$f2", "$8", "$9", "$10", "$11", "$13", "memory"
-           );
-      } else {
-        mmA = _mm_load_si64((__m64 *)&inptr[0]);
-        mmF = _mm_load_si64((__m64 *)&inptr[8]);
-        mmD = _mm_load_si64((__m64 *)&inptr[16]);
-        mmC = _mm_load_si64((__m64 *)&inptr[24]);
-        inptr += RGB_PIXELSIZE * 8;
-      }
-      mmB = mmA;
-      mmA = _mm_unpacklo_pi8(mmA, mmF);
-      mmB = _mm_unpackhi_pi8(mmB, mmF);
-
-      mmG = mmD;
-      mmD = _mm_unpacklo_pi8(mmD, mmC);
-      mmG = _mm_unpackhi_pi8(mmG, mmC);
-
-      mmE = mmA;
-      mmA = _mm_unpacklo_pi16(mmA, mmD);
-      mmE = _mm_unpackhi_pi16(mmE, mmD);
-
-      mmH = mmB;
-      mmB = _mm_unpacklo_pi16(mmB, mmG);
-      mmH = _mm_unpackhi_pi16(mmH, mmG);
-
-      mmC = mmA;
-      mmA = _mm_loadlo_pi8_f(mmA);
-      mmC = _mm_loadhi_pi8_f(mmC);
-
-      mmD = mmB;
-      mmB = _mm_loadlo_pi8_f(mmB);
-      mmD = _mm_loadhi_pi8_f(mmD);
-
-      mmG = mmE;
-      mmE = _mm_loadlo_pi8_f(mmE);
-      mmG = _mm_loadhi_pi8_f(mmG);
-
-      mmF = mmH;
-      mmF = _mm_unpacklo_pi8(mmF, mmH);
-      mmH = _mm_unpackhi_pi8(mmH, mmH);
-      mmF = _mm_srli_pi16(mmF, BYTE_BIT);
-      mmH = _mm_srli_pi16(mmH, BYTE_BIT);
-
-#endif
-
-      wk[0] = mm0;
-      wk[1] = mm1;
-      wk[2] = mm4;
-      wk[3] = mm5;
-
-      mm6 = mm1;
-      mm1 = _mm_unpacklo_pi16(mm1, mm3);
-      mm6 = _mm_unpackhi_pi16(mm6, mm3);
-      mm7 = mm1;
-      mm4 = mm6;
-      mm1 = _mm_madd_pi16(mm1, PW_F0299_F0337);
-      mm6 = _mm_madd_pi16(mm6, PW_F0299_F0337);
-      mm7 = _mm_madd_pi16(mm7, PW_MF016_MF033);
-      mm4 = _mm_madd_pi16(mm4, PW_MF016_MF033);
-
-      wk[4] = mm1;
-      wk[5] = mm6;
-
-      mm1 = _mm_loadlo_pi16_f(mm5);
-      mm6 = _mm_loadhi_pi16_f(mm5);
-      mm1 = _mm_srli_pi32(mm1, 1);
-      mm6 = _mm_srli_pi32(mm6, 1);
-
-      mm5 = PD_ONEHALFM1_CJ;
-      mm7 = _mm_add_pi32(mm7, mm1);
-      mm4 = _mm_add_pi32(mm4, mm6);
-      mm7 = _mm_add_pi32(mm7, mm5);
-      mm4 = _mm_add_pi32(mm4, mm5);
-      mm7 = _mm_srli_pi32(mm7, SCALEBITS);
-      mm4 = _mm_srli_pi32(mm4, SCALEBITS);
-      mm7 = _mm_packs_pi32(mm7, mm4);
-
-      mm1 = wk[2];
-      mm6 = mm0;
-      mm0 = _mm_unpacklo_pi16(mm0, mm2);
-      mm6 = _mm_unpackhi_pi16(mm6, mm2);
-      mm5 = mm0;
-      mm4 = mm6;
-      mm0 = _mm_madd_pi16(mm0, PW_F0299_F0337);
-      mm6 = _mm_madd_pi16(mm6, PW_F0299_F0337);
-      mm5 = _mm_madd_pi16(mm5, PW_MF016_MF033);
-      mm4 = _mm_madd_pi16(mm4, PW_MF016_MF033);
-
-      wk[6] = mm0;
-      wk[7] = mm6;
-      mm0 = _mm_loadlo_pi16_f(mm1);
-      mm6 = _mm_loadhi_pi16_f(mm1);
-      mm0 = _mm_srli_pi32(mm0, 1);
-      mm6 = _mm_srli_pi32(mm6, 1);
-
-      mm1 = PD_ONEHALFM1_CJ;
-      mm5 = _mm_add_pi32(mm5, mm0);
-      mm4 = _mm_add_pi32(mm4, mm6);
-      mm5 = _mm_add_pi32(mm5, mm1);
-      mm4 = _mm_add_pi32(mm4, mm1);
-      mm5 = _mm_srli_pi32(mm5, SCALEBITS);
-      mm4 = _mm_srli_pi32(mm4, SCALEBITS);
-      mm5 = _mm_packs_pi32(mm5, mm4);
-
-      mm7 = _mm_slli_pi16(mm7, BYTE_BIT);
-      mm5  = _mm_or_si64(mm5, mm7);
-      Cb_RG = mm5;
-
-      mm0 = wk[3];
-      mm6 = wk[2];
-      mm1 = wk[1];
-
-      mm4 = mm0;
-      mm0 = _mm_unpacklo_pi16(mm0, mm3);
-      mm4 = _mm_unpackhi_pi16(mm4, mm3);
-      mm7 = mm0;
-      mm5 = mm4;
-      mm0 = _mm_madd_pi16(mm0, PW_F0114_F0250);
-      mm4 = _mm_madd_pi16(mm4, PW_F0114_F0250);
-      mm7 = _mm_madd_pi16(mm7, PW_MF008_MF041);
-      mm5 = _mm_madd_pi16(mm5, PW_MF008_MF041);
-
-      mm3 = PD_ONEHALF;
-      mm0 = _mm_add_pi32(mm0, wk[4]);
-      mm4 = _mm_add_pi32(mm4, wk[5]);
-      mm0 = _mm_add_pi32(mm0, mm3);
-      mm4 = _mm_add_pi32(mm4, mm3);
-      mm0 = _mm_srli_pi32(mm0, SCALEBITS);
-      mm4 = _mm_srli_pi32(mm4, SCALEBITS);
-      mm0 = _mm_packs_pi32(mm0, mm4);
-
-      mm3 = _mm_loadlo_pi16_f(mm1);
-      mm4 = _mm_loadhi_pi16_f(mm1);
-      mm3 = _mm_srli_pi32(mm3, 1);
-      mm4 = _mm_srli_pi32(mm4, 1);
-
-      mm1 = PD_ONEHALFM1_CJ;
-      mm7 = _mm_add_pi32(mm7, mm3);
-      mm5 = _mm_add_pi32(mm5, mm4);
-      mm7 = _mm_add_pi32(mm7, mm1);
-      mm5 = _mm_add_pi32(mm5, mm1);
-      mm7 = _mm_srli_pi32(mm7, SCALEBITS);
-      mm5 = _mm_srli_pi32(mm5, SCALEBITS);
-      mm7 = _mm_packs_pi32(mm7, mm5);
-
-      mm3 = wk[0];
-      mm4 = mm6;
-      mm6 = _mm_unpacklo_pi16(mm6, mm2);
-      mm4 = _mm_unpackhi_pi16(mm4, mm2);
-      mm1 = mm6;
-      mm5 = mm4;
-      mm6 = _mm_madd_pi16(mm6, PW_F0114_F0250);
-      mm4 = _mm_madd_pi16(mm4, PW_F0114_F0250);
-      mm1 = _mm_madd_pi16(mm1, PW_MF008_MF041);
-      mm5 = _mm_madd_pi16(mm5, PW_MF008_MF041);
-
-      mm2 = PD_ONEHALF;
-      mm6 = _mm_add_pi32(mm6, wk[6]);
-      mm4 = _mm_add_pi32(mm4, wk[7]);
-      mm6 = _mm_add_pi32(mm6, mm2);
-      mm4 = _mm_add_pi32(mm4, mm2);
-      mm6 = _mm_srli_pi32(mm6, SCALEBITS);
-      mm4 = _mm_srli_pi32(mm4, SCALEBITS);
-      mm6 = _mm_packs_pi32(mm6, mm4);
-
-      mm0 = _mm_slli_pi16(mm0, BYTE_BIT);
-      mm6 = _mm_or_si64(mm6, mm0);
-      Y_BG = mm6;
-
-      mm2 = _mm_loadlo_pi16_f(mm3);
-      mm4 = _mm_loadhi_pi16_f(mm3);
-      mm2 = _mm_srli_pi32(mm2, 1);
-      mm4 = _mm_srli_pi32(mm4, 1);
-
-      mm0 = PD_ONEHALFM1_CJ;
-      mm1 = _mm_add_pi32(mm1, mm2);
-      mm5 = _mm_add_pi32(mm5, mm4);
-      mm1 = _mm_add_pi32(mm1, mm0);
-      mm5 = _mm_add_pi32(mm5, mm0);
-      mm1 = _mm_srli_pi32(mm1, SCALEBITS);
-      mm5 = _mm_srli_pi32(mm5, SCALEBITS);
-      mm1 = _mm_packs_pi32(mm1, mm5);
-
-      mm7 = _mm_slli_pi16(mm7, BYTE_BIT);
-      mm1 = _mm_or_si64(mm1, mm7);
-      Cr_BG = mm1;
-
-      _mm_store_si64((__m64 *)&outptr0[0], Y_BG);
-      _mm_store_si64((__m64 *)&outptr1[0], Cb_RG);
-      _mm_store_si64((__m64 *)&outptr2[0], Cr_BG);
-    }
-  }
-}
-
-#undef mmA
-#undef mmB
-#undef mmC
-#undef mmD
-#undef mmE
-#undef mmF
-#undef mmG
-#undef mmH
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jccolor-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jccolor-mmi.c
deleted file mode 100644
index 93ef5c7..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jccolor-mmi.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2011, 2014, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* RGB --> YCC CONVERSION */
-
-#include "jsimd_mmi.h"
-
-
-#define F_0_081  ((short)5329)                /* FIX(0.08131) */
-#define F_0_114  ((short)7471)                /* FIX(0.11400) */
-#define F_0_168  ((short)11059)               /* FIX(0.16874) */
-#define F_0_250  ((short)16384)               /* FIX(0.25000) */
-#define F_0_299  ((short)19595)               /* FIX(0.29900) */
-#define F_0_331  ((short)21709)               /* FIX(0.33126) */
-#define F_0_418  ((short)27439)               /* FIX(0.41869) */
-#define F_0_587  ((short)38470)               /* FIX(0.58700) */
-#define F_0_337  ((short)(F_0_587 - F_0_250)) /* FIX(0.58700) - FIX(0.25000) */
-
-enum const_index {
-  index_PD_ONEHALF,
-  index_PW_F0299_F0337,
-  index_PW_F0114_F0250,
-  index_PW_MF016_MF033,
-  index_PW_MF008_MF041,
-  index_PD_ONEHALFM1_CJ
-};
-
-static uint64_t const_value[] = {
-  _uint64_set_pi32((int)(1 << (SCALEBITS - 1)), (int)(1 << (SCALEBITS - 1))),
-  _uint64_set_pi16(F_0_337, F_0_299, F_0_337, F_0_299),
-  _uint64_set_pi16(F_0_250, F_0_114, F_0_250, F_0_114),
-  _uint64_set_pi16(-F_0_331, -F_0_168, -F_0_331, -F_0_168),
-  _uint64_set_pi16(-F_0_418, -F_0_081, -F_0_418, -F_0_081),
-  _uint64_set_pi32(((1 << (SCALEBITS - 1)) - 1 + (CENTERJSAMPLE << SCALEBITS)),
-                   ((1 << (SCALEBITS - 1)) - 1 + (CENTERJSAMPLE << SCALEBITS)))
-};
-
-#define get_const_value(index)  (*(__m64 *)&const_value[index])
-
-#define PD_ONEHALF       get_const_value(index_PD_ONEHALF)
-#define PW_F0299_F0337   get_const_value(index_PW_F0299_F0337)
-#define PW_F0114_F0250   get_const_value(index_PW_F0114_F0250)
-#define PW_MF016_MF033   get_const_value(index_PW_MF016_MF033)
-#define PW_MF008_MF041   get_const_value(index_PW_MF008_MF041)
-#define PD_ONEHALFM1_CJ  get_const_value(index_PD_ONEHALFM1_CJ)
-
-
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-
-#define RGB_RED  EXT_RGB_RED
-#define RGB_GREEN  EXT_RGB_GREEN
-#define RGB_BLUE  EXT_RGB_BLUE
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extrgb_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
-
-#define RGB_RED  EXT_RGBX_RED
-#define RGB_GREEN  EXT_RGBX_GREEN
-#define RGB_BLUE  EXT_RGBX_BLUE
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extrgbx_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
-
-#define RGB_RED  EXT_BGR_RED
-#define RGB_GREEN  EXT_BGR_GREEN
-#define RGB_BLUE  EXT_BGR_BLUE
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extbgr_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
-
-#define RGB_RED  EXT_BGRX_RED
-#define RGB_GREEN  EXT_BGRX_GREEN
-#define RGB_BLUE  EXT_BGRX_BLUE
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extbgrx_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
-
-#define RGB_RED  EXT_XBGR_RED
-#define RGB_GREEN  EXT_XBGR_GREEN
-#define RGB_BLUE  EXT_XBGR_BLUE
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extxbgr_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
-
-#define RGB_RED  EXT_XRGB_RED
-#define RGB_GREEN  EXT_XRGB_GREEN
-#define RGB_BLUE  EXT_XRGB_BLUE
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define jsimd_rgb_ycc_convert_mmi  jsimd_extxrgb_ycc_convert_mmi
-#include "jccolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_rgb_ycc_convert_mmi
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jcsample-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jcsample-mmi.c
deleted file mode 100644
index 2f2d851..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jcsample-mmi.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, 2018, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* CHROMA DOWNSAMPLING */
-
-#include "jsimd_mmi.h"
-#include "jcsample.h"
-
-
-void jsimd_h2v2_downsample_mmi(JDIMENSION image_width, int max_v_samp_factor,
-                               JDIMENSION v_samp_factor,
-                               JDIMENSION width_in_blocks,
-                               JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  int inrow, outrow, outcol, bias;
-  JDIMENSION output_cols = width_in_blocks * DCTSIZE;
-  JSAMPROW inptr0, inptr1, outptr;
-  __m64 mm0, mm1, mm2, mm3, mm4, mm5, mm6 = 0.0, mm7;
-
-  expand_right_edge(input_data, max_v_samp_factor, image_width,
-                    output_cols * 2);
-
-  bias = (1 << 17) + 1;                      /* 0x00020001 (bias pattern) */
-  mm7 = _mm_set1_pi32(bias);                 /* mm7={1, 2, 1, 2} */
-  mm6 = _mm_cmpeq_pi16(mm6, mm6);
-  mm6 = _mm_srli_pi16(mm6, BYTE_BIT);        /* mm6={0xFF 0x00 0xFF 0x00 ..} */
-
-  for (inrow = 0, outrow = 0; outrow < v_samp_factor;
-       inrow += 2, outrow++) {
-
-    inptr0 = input_data[inrow];
-    inptr1 = input_data[inrow + 1];
-    outptr = output_data[outrow];
-
-    for (outcol = output_cols; outcol > 0;
-         outcol -= 8, inptr0 += 16, inptr1 += 16, outptr += 8) {
-
-      mm0 = _mm_load_si64((__m64 *)&inptr0[0]);
-      mm1 = _mm_load_si64((__m64 *)&inptr1[0]);
-      mm2 = _mm_load_si64((__m64 *)&inptr0[8]);
-      mm3 = _mm_load_si64((__m64 *)&inptr1[8]);
-
-      mm4 = mm0;
-      mm5 = mm1;
-      mm0 = _mm_and_si64(mm0, mm6);
-      mm4 = _mm_srli_pi16(mm4, BYTE_BIT);
-      mm1 = _mm_and_si64(mm1, mm6);
-      mm5 = _mm_srli_pi16(mm5, BYTE_BIT);
-      mm0 = _mm_add_pi16(mm0, mm4);
-      mm1 = _mm_add_pi16(mm1, mm5);
-
-      mm4 = mm2;
-      mm5 = mm3;
-      mm2 = _mm_and_si64(mm2, mm6);
-      mm4 = _mm_srli_pi16(mm4, BYTE_BIT);
-      mm3 = _mm_and_si64(mm3, mm6);
-      mm5 = _mm_srli_pi16(mm5, BYTE_BIT);
-      mm2 = _mm_add_pi16(mm2, mm4);
-      mm3 = _mm_add_pi16(mm3, mm5);
-
-      mm0 = _mm_add_pi16(mm0, mm1);
-      mm2 = _mm_add_pi16(mm2, mm3);
-      mm0 = _mm_add_pi16(mm0, mm7);
-      mm2 = _mm_add_pi16(mm2, mm7);
-      mm0 = _mm_srli_pi16(mm0, 2);
-      mm2 = _mm_srli_pi16(mm2, 2);
-
-      mm0 = _mm_packs_pu16(mm0, mm2);
-
-      _mm_store_si64((__m64 *)&outptr[0], mm0);
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jcsample.h b/src/third_party/libjpeg-turbo/simd/loongson/jcsample.h
deleted file mode 100644
index 2ac4816..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jcsample.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * jcsample.h
- *
- * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1991-1996, Thomas G. Lane.
- * For conditions of distribution and use, see the accompanying README.ijg
- * file.
- */
-
-LOCAL(void)
-expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
-                  JDIMENSION output_cols)
-{
-  register JSAMPROW ptr;
-  register JSAMPLE pixval;
-  register int count;
-  int row;
-  int numcols = (int)(output_cols - input_cols);
-
-  if (numcols > 0) {
-    for (row = 0; row < num_rows; row++) {
-      ptr = image_data[row] + input_cols;
-      pixval = ptr[-1];         /* don't need GETJSAMPLE() here */
-      for (count = numcols; count > 0; count--)
-        *ptr++ = pixval;
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jdcolext-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jdcolext-mmi.c
deleted file mode 100644
index 560d9b0..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jdcolext-mmi.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jdcolor-mmi.c */
-
-
-#if RGB_RED == 0
-#define mmA  mm0
-#define mmB  mm1
-#elif RGB_GREEN == 0
-#define mmA  mm2
-#define mmB  mm3
-#elif RGB_BLUE == 0
-#define mmA  mm4
-#define mmB  mm5
-#else
-#define mmA  mm6
-#define mmB  mm7
-#endif
-
-#if RGB_RED == 1
-#define mmC  mm0
-#define mmD  mm1
-#elif RGB_GREEN == 1
-#define mmC  mm2
-#define mmD  mm3
-#elif RGB_BLUE == 1
-#define mmC  mm4
-#define mmD  mm5
-#else
-#define mmC  mm6
-#define mmD  mm7
-#endif
-
-#if RGB_RED == 2
-#define mmE  mm0
-#define mmF  mm1
-#elif RGB_GREEN == 2
-#define mmE  mm2
-#define mmF  mm3
-#elif RGB_BLUE == 2
-#define mmE  mm4
-#define mmF  mm5
-#else
-#define mmE  mm6
-#define mmF  mm7
-#endif
-
-#if RGB_RED == 3
-#define mmG  mm0
-#define mmH  mm1
-#elif RGB_GREEN == 3
-#define mmG  mm2
-#define mmH  mm3
-#elif RGB_BLUE == 3
-#define mmG  mm4
-#define mmH  mm5
-#else
-#define mmG  mm6
-#define mmH  mm7
-#endif
-
-
-void jsimd_ycc_rgb_convert_mmi(JDIMENSION out_width, JSAMPIMAGE input_buf,
-                               JDIMENSION input_row, JSAMPARRAY output_buf,
-                               int num_rows)
-{
-  JSAMPROW outptr, inptr0, inptr1, inptr2;
-  int num_cols, col;
-  __m64 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
-  __m64 mm8, wk[2];
-
-  while (--num_rows >= 0) {
-    inptr0 = input_buf[0][input_row];
-    inptr1 = input_buf[1][input_row];
-    inptr2 = input_buf[2][input_row];
-    input_row++;
-    outptr = *output_buf++;
-
-    for (num_cols = out_width; num_cols > 0; num_cols -= 8,
-         inptr0 += 8, inptr1 += 8, inptr2 += 8) {
-
-      mm5 = _mm_load_si64((__m64 *)inptr1);
-      mm1 = _mm_load_si64((__m64 *)inptr2);
-      mm8 = _mm_load_si64((__m64 *)inptr0);
-      mm4 = 0;
-      mm7 = 0;
-      mm4 = _mm_cmpeq_pi16(mm4, mm4);
-      mm7 = _mm_cmpeq_pi16(mm7, mm7);
-      mm4 = _mm_srli_pi16(mm4, BYTE_BIT);
-      mm7 = _mm_slli_pi16(mm7, 7);      /* mm7={0xFF80 0xFF80 0xFF80 0xFF80} */
-      mm0 = mm4;                        /* mm0=mm4={0xFF 0x00 0xFF 0x00 ..} */
-
-      mm4 = _mm_and_si64(mm4, mm5);           /* mm4=Cb(0246)=CbE */
-      mm5 = _mm_srli_pi16(mm5, BYTE_BIT);     /* mm5=Cb(1357)=CbO */
-      mm0 = _mm_and_si64(mm0, mm1);           /* mm0=Cr(0246)=CrE */
-      mm1 = _mm_srli_pi16(mm1, BYTE_BIT);     /* mm1=Cr(1357)=CrO */
-      mm4 = _mm_add_pi16(mm4, mm7);
-      mm5 = _mm_add_pi16(mm5, mm7);
-      mm0 = _mm_add_pi16(mm0, mm7);
-      mm1 = _mm_add_pi16(mm1, mm7);
-
-      /* (Original)
-       * R = Y                + 1.40200 * Cr
-       * G = Y - 0.34414 * Cb - 0.71414 * Cr
-       * B = Y + 1.77200 * Cb
-       *
-       * (This implementation)
-       * R = Y                + 0.40200 * Cr + Cr
-       * G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
-       * B = Y - 0.22800 * Cb + Cb + Cb
-       */
-
-      mm2 = mm4;                              /* mm2 = CbE */
-      mm3 = mm5;                              /* mm3 = CbO */
-      mm4 = _mm_add_pi16(mm4, mm4);           /* mm4 = 2*CbE */
-      mm5 = _mm_add_pi16(mm5, mm5);           /* mm5 = 2*CbO */
-      mm6 = mm0;                              /* mm6 = CrE */
-      mm7 = mm1;                              /* mm7 = CrO */
-      mm0 = _mm_add_pi16(mm0, mm0);           /* mm0 = 2*CrE */
-      mm1 = _mm_add_pi16(mm1, mm1);           /* mm1 = 2*CrO */
-
-      mm4 = _mm_mulhi_pi16(mm4, PW_MF0228);   /* mm4=(2*CbE * -FIX(0.22800) */
-      mm5 = _mm_mulhi_pi16(mm5, PW_MF0228);   /* mm5=(2*CbO * -FIX(0.22800) */
-      mm0 = _mm_mulhi_pi16(mm0, PW_F0402);    /* mm0=(2*CrE * FIX(0.40200)) */
-      mm1 = _mm_mulhi_pi16(mm1, PW_F0402);    /* mm1=(2*CrO * FIX(0.40200)) */
-
-      mm4 = _mm_add_pi16(mm4, PW_ONE);
-      mm5 = _mm_add_pi16(mm5, PW_ONE);
-      mm4 = _mm_srai_pi16(mm4, 1);            /* mm4=(CbE * -FIX(0.22800)) */
-      mm5 = _mm_srai_pi16(mm5, 1);            /* mm5=(CbO * -FIX(0.22800)) */
-      mm0 = _mm_add_pi16(mm0, PW_ONE);
-      mm1 = _mm_add_pi16(mm1, PW_ONE);
-      mm0 = _mm_srai_pi16(mm0, 1);            /* mm0=(CrE * FIX(0.40200)) */
-      mm1 = _mm_srai_pi16(mm1, 1);            /* mm1=(CrO * FIX(0.40200)) */
-
-      mm4 = _mm_add_pi16(mm4, mm2);
-      mm5 = _mm_add_pi16(mm5, mm3);
-      mm4 = _mm_add_pi16(mm4, mm2);       /* mm4=(CbE * FIX(1.77200))=(B-Y)E */
-      mm5 = _mm_add_pi16(mm5, mm3);       /* mm5=(CbO * FIX(1.77200))=(B-Y)O */
-      mm0 = _mm_add_pi16(mm0, mm6);       /* mm0=(CrE * FIX(1.40200))=(R-Y)E */
-      mm1 = _mm_add_pi16(mm1, mm7);       /* mm1=(CrO * FIX(1.40200))=(R-Y)O */
-
-      wk[0] = mm4;                            /* wk(0)=(B-Y)E */
-      wk[1] = mm5;                            /* wk(1)=(B-Y)O */
-
-      mm4 = mm2;
-      mm5 = mm3;
-      mm2 = _mm_unpacklo_pi16(mm2, mm6);
-      mm4 = _mm_unpackhi_pi16(mm4, mm6);
-      mm2 = _mm_madd_pi16(mm2, PW_MF0344_F0285);
-      mm4 = _mm_madd_pi16(mm4, PW_MF0344_F0285);
-      mm3 = _mm_unpacklo_pi16(mm3, mm7);
-      mm5 = _mm_unpackhi_pi16(mm5, mm7);
-      mm3 = _mm_madd_pi16(mm3, PW_MF0344_F0285);
-      mm5 = _mm_madd_pi16(mm5, PW_MF0344_F0285);
-
-      mm2 = _mm_add_pi32(mm2, PD_ONEHALF);
-      mm4 = _mm_add_pi32(mm4, PD_ONEHALF);
-      mm2 = _mm_srai_pi32(mm2, SCALEBITS);
-      mm4 = _mm_srai_pi32(mm4, SCALEBITS);
-      mm3 = _mm_add_pi32(mm3, PD_ONEHALF);
-      mm5 = _mm_add_pi32(mm5, PD_ONEHALF);
-      mm3 = _mm_srai_pi32(mm3, SCALEBITS);
-      mm5 = _mm_srai_pi32(mm5, SCALEBITS);
-
-      mm2 = _mm_packs_pi32(mm2, mm4);  /* mm2=CbE*-FIX(0.344)+CrE*FIX(0.285) */
-      mm3 = _mm_packs_pi32(mm3, mm5);  /* mm3=CbO*-FIX(0.344)+CrO*FIX(0.285) */
-      mm2 = _mm_sub_pi16(mm2, mm6);  /* mm2=CbE*-FIX(0.344)+CrE*-FIX(0.714)=(G-Y)E */
-      mm3 = _mm_sub_pi16(mm3, mm7);  /* mm3=CbO*-FIX(0.344)+CrO*-FIX(0.714)=(G-Y)O */
-
-      mm5 = mm8;                              /* mm5=Y(01234567) */
-
-      mm4 = _mm_cmpeq_pi16(mm4, mm4);
-      mm4 = _mm_srli_pi16(mm4, BYTE_BIT);    /* mm4={0xFF 0x00 0xFF 0x00 ..} */
-      mm4 = _mm_and_si64(mm4, mm5);          /* mm4=Y(0246)=YE */
-      mm5 = _mm_srli_pi16(mm5, BYTE_BIT);    /* mm5=Y(1357)=YO */
-
-      mm0 = _mm_add_pi16(mm0, mm4);      /* mm0=((R-Y)E+YE)=RE=(R0 R2 R4 R6) */
-      mm1 = _mm_add_pi16(mm1, mm5);      /* mm1=((R-Y)O+YO)=RO=(R1 R3 R5 R7) */
-      mm0 = _mm_packs_pu16(mm0, mm0);    /* mm0=(R0 R2 R4 R6 ** ** ** **) */
-      mm1 = _mm_packs_pu16(mm1, mm1);    /* mm1=(R1 R3 R5 R7 ** ** ** **) */
-
-      mm2 = _mm_add_pi16(mm2, mm4);      /* mm2=((G-Y)E+YE)=GE=(G0 G2 G4 G6) */
-      mm3 = _mm_add_pi16(mm3, mm5);      /* mm3=((G-Y)O+YO)=GO=(G1 G3 G5 G7) */
-      mm2 = _mm_packs_pu16(mm2, mm2);    /* mm2=(G0 G2 G4 G6 ** ** ** **) */
-      mm3 = _mm_packs_pu16(mm3, mm3);    /* mm3=(G1 G3 G5 G7 ** ** ** **) */
-
-      mm4 = _mm_add_pi16(mm4, wk[0]);    /* mm4=(YE+(B-Y)E)=BE=(B0 B2 B4 B6) */
-      mm5 = _mm_add_pi16(mm5, wk[1]);    /* mm5=(YO+(B-Y)O)=BO=(B1 B3 B5 B7) */
-      mm4 = _mm_packs_pu16(mm4, mm4);    /* mm4=(B0 B2 B4 B6 ** ** ** **) */
-      mm5 = _mm_packs_pu16(mm5, mm5);    /* mm5=(B1 B3 B5 B7 ** ** ** **) */
-
-#if RGB_PIXELSIZE == 3
-
-      /* mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **) */
-      /* mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **) */
-      mmA = _mm_unpacklo_pi8(mmA, mmC);     /* mmA=(00 10 02 12 04 14 06 16) */
-      mmE = _mm_unpacklo_pi8(mmE, mmB);     /* mmE=(20 01 22 03 24 05 26 07) */
-      mmD = _mm_unpacklo_pi8(mmD, mmF);     /* mmD=(11 21 13 23 15 25 17 27) */
-
-      mmG = mmA;
-      mmH = mmA;
-      mmA = _mm_unpacklo_pi16(mmA, mmE);    /* mmA=(00 10 20 01 02 12 22 03) */
-      mmG = _mm_unpackhi_pi16(mmG, mmE);    /* mmG=(04 14 24 05 06 16 26 07) */
-
-      mmH = _mm_srli_si64(mmH, 2 * BYTE_BIT);
-      mmE = _mm_srli_si64(mmE, 2 * BYTE_BIT);
-
-      mmC = mmD;
-      mmB = mmD;
-      mmD = _mm_unpacklo_pi16(mmD, mmH);    /* mmD=(11 21 02 12 13 23 04 14) */
-      mmC = _mm_unpackhi_pi16(mmC, mmH);    /* mmC=(15 25 06 16 17 27 -- --) */
-
-      mmB = _mm_srli_si64(mmB, 2 * BYTE_BIT); /* mmB=(13 23 15 25 17 27 -- --) */
-
-      mmF = mmE;
-      mmE = _mm_unpacklo_pi16(mmE, mmB);    /* mmE=(22 03 13 23 24 05 15 25) */
-      mmF = _mm_unpackhi_pi16(mmF, mmB);    /* mmF=(26 07 17 27 -- -- -- --) */
-
-      mmA = _mm_unpacklo_pi32(mmA, mmD);    /* mmA=(00 10 20 01 11 21 02 12) */
-      mmE = _mm_unpacklo_pi32(mmE, mmG);    /* mmE=(22 03 13 23 04 14 24 05) */
-      mmC = _mm_unpacklo_pi32(mmC, mmF);    /* mmC=(15 25 06 16 26 07 17 27) */
-
-      if (num_cols >= 8) {
-        _mm_store_si64((__m64 *)outptr, mmA);
-        _mm_store_si64((__m64 *)(outptr + 8), mmE);
-        _mm_store_si64((__m64 *)(outptr + 16), mmC);
-        outptr += RGB_PIXELSIZE * 8;
-      } else {
-        col = num_cols * 3;
-        asm(".set noreorder\r\n"
-
-            "li      $8, 16\r\n"
-            "move    $9, %4\r\n"
-            "mov.s   $f4, %1\r\n"
-            "mov.s   $f6, %3\r\n"
-            "move    $10, %5\r\n"
-            "bltu    $9, $8, 1f\r\n"
-            "nop     \r\n"
-            "gssdlc1 $f4, 7($10)\r\n"
-            "gssdrc1 $f4, 0($10)\r\n"
-            "gssdlc1 $f6, 7+8($10)\r\n"
-            "gssdrc1 $f6, 8($10)\r\n"
-            "mov.s   $f4, %2\r\n"
-            "subu    $9, $9, 16\r\n"
-            "daddu   $10, $10, 16\r\n"
-            "b       2f\r\n"
-            "nop     \r\n"
-
-            "1:      \r\n"
-            "li      $8, 8\r\n"               /* st8 */
-            "bltu    $9, $8, 2f\r\n"
-            "nop     \r\n"
-            "gssdlc1 $f4, 7($10)\r\n"
-            "gssdrc1 $f4, ($10)\r\n"
-            "mov.s   $f4, %3\r\n"
-            "subu    $9, $9, 8\r\n"
-            "daddu   $10, $10, 8\r\n"
-
-            "2:      \r\n"
-            "li      $8, 4\r\n"               /* st4 */
-            "mfc1    $11, $f4\r\n"
-            "bltu    $9, $8, 3f\r\n"
-            "nop     \r\n"
-            "swl     $11, 3($10)\r\n"
-            "swr     $11, 0($10)\r\n"
-            "li      $8, 32\r\n"
-            "mtc1    $8, $f6\r\n"
-            "dsrl    $f4, $f4, $f6\r\n"
-            "mfc1    $11, $f4\r\n"
-            "subu    $9, $9, 4\r\n"
-            "daddu   $10, $10, 4\r\n"
-
-            "3:      \r\n"
-            "li      $8, 2\r\n"               /* st2 */
-            "bltu    $9, $8, 4f\r\n"
-            "nop     \r\n"
-            "ush     $11, 0($10)\r\n"
-            "srl     $11, 16\r\n"
-            "subu    $9, $9, 2\r\n"
-            "daddu   $10, $10, 2\r\n"
-
-            "4:      \r\n"
-            "li      $8, 1\r\n"               /* st1 */
-            "bltu    $9, $8, 5f\r\n"
-            "nop     \r\n"
-            "sb      $11, 0($10)\r\n"
-
-            "5:      \r\n"
-            "nop     \r\n"                    /* end */
-            : "=m" (*outptr)
-            : "f" (mmA), "f" (mmC), "f" (mmE), "r" (col), "r" (outptr)
-            : "$f4", "$f6", "$8", "$9", "$10", "$11", "memory"
-           );
-      }
-
-#else  /* RGB_PIXELSIZE == 4 */
-
-#ifdef RGBX_FILLER_0XFF
-      mm6 = _mm_cmpeq_pi8(mm6, mm6);
-      mm7 = _mm_cmpeq_pi8(mm7, mm7);
-#else
-      mm6 = _mm_xor_si64(mm6, mm6);
-      mm7 = _mm_xor_si64(mm7, mm7);
-#endif
-      /* mmA=(00 02 04 06 ** ** ** **), mmB=(01 03 05 07 ** ** ** **) */
-      /* mmC=(10 12 14 16 ** ** ** **), mmD=(11 13 15 17 ** ** ** **) */
-      /* mmE=(20 22 24 26 ** ** ** **), mmF=(21 23 25 27 ** ** ** **) */
-      /* mmG=(30 32 34 36 ** ** ** **), mmH=(31 33 35 37 ** ** ** **) */
-
-      mmA = _mm_unpacklo_pi8(mmA, mmC);     /* mmA=(00 10 02 12 04 14 06 16) */
-      mmE = _mm_unpacklo_pi8(mmE, mmG);     /* mmE=(20 30 22 32 24 34 26 36) */
-      mmB = _mm_unpacklo_pi8(mmB, mmD);     /* mmB=(01 11 03 13 05 15 07 17) */
-      mmF = _mm_unpacklo_pi8(mmF, mmH);     /* mmF=(21 31 23 33 25 35 27 37) */
-
-      mmC = mmA;
-      mmA = _mm_unpacklo_pi16(mmA, mmE);    /* mmA=(00 10 20 30 02 12 22 32) */
-      mmC = _mm_unpackhi_pi16(mmC, mmE);    /* mmC=(04 14 24 34 06 16 26 36) */
-      mmG = mmB;
-      mmB = _mm_unpacklo_pi16(mmB, mmF);    /* mmB=(01 11 21 31 03 13 23 33) */
-      mmG = _mm_unpackhi_pi16(mmG, mmF);    /* mmG=(05 15 25 35 07 17 27 37) */
-
-      mmD = mmA;
-      mmA = _mm_unpacklo_pi32(mmA, mmB);    /* mmA=(00 10 20 30 01 11 21 31) */
-      mmD = _mm_unpackhi_pi32(mmD, mmB);    /* mmD=(02 12 22 32 03 13 23 33) */
-      mmH = mmC;
-      mmC = _mm_unpacklo_pi32(mmC, mmG);    /* mmC=(04 14 24 34 05 15 25 35) */
-      mmH = _mm_unpackhi_pi32(mmH, mmG);    /* mmH=(06 16 26 36 07 17 27 37) */
-
-      if (num_cols >= 8) {
-        _mm_store_si64((__m64 *)outptr, mmA);
-        _mm_store_si64((__m64 *)(outptr + 8), mmD);
-        _mm_store_si64((__m64 *)(outptr + 16), mmC);
-        _mm_store_si64((__m64 *)(outptr + 24), mmH);
-        outptr += RGB_PIXELSIZE * 8;
-      } else {
-        col = num_cols;
-        asm(".set noreorder\r\n"              /* st16 */
-
-            "li      $8, 4\r\n"
-            "move    $9, %6\r\n"
-            "move    $10, %7\r\n"
-            "mov.s   $f4, %2\r\n"
-            "mov.s   $f6, %4\r\n"
-            "bltu    $9, $8, 1f\r\n"
-            "nop     \r\n"
-            "gssdlc1 $f4, 7($10)\r\n"
-            "gssdrc1 $f4, ($10)\r\n"
-            "gssdlc1 $f6, 7+8($10)\r\n"
-            "gssdrc1 $f6, 8($10)\r\n"
-            "mov.s   $f4, %3\r\n"
-            "mov.s   $f6, %5\r\n"
-            "subu    $9, $9, 4\r\n"
-            "daddu   $10, $10, 16\r\n"
-
-            "1:      \r\n"
-            "li      $8, 2\r\n"               /* st8 */
-            "bltu    $9, $8, 2f\r\n"
-            "nop     \r\n"
-            "gssdlc1 $f4, 7($10)\r\n"
-            "gssdrc1 $f4, 0($10)\r\n"
-            "mov.s   $f4, $f6\r\n"
-            "subu    $9, $9, 2\r\n"
-            "daddu   $10, $10, 8\r\n"
-
-            "2:      \r\n"
-            "li      $8, 1\r\n"               /* st4 */
-            "bltu    $9, $8, 3f\r\n"
-            "nop     \r\n"
-            "gsswlc1 $f4, 3($10)\r\n"
-            "gsswrc1 $f4, 0($10)\r\n"
-
-            "3:      \r\n"
-            "li      %1, 0\r\n"               /* end */
-            : "=m" (*outptr), "=r" (col)
-            : "f" (mmA), "f" (mmC), "f" (mmD), "f" (mmH), "r" (col),
-              "r" (outptr)
-            : "$f4", "$f6", "$8", "$9", "$10", "memory"
-           );
-      }
-
-#endif
-
-    }
-  }
-}
-
-#undef mmA
-#undef mmB
-#undef mmC
-#undef mmD
-#undef mmE
-#undef mmF
-#undef mmG
-#undef mmH
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jdcolor-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jdcolor-mmi.c
deleted file mode 100644
index 2c58263..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jdcolor-mmi.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2011, 2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* YCC --> RGB CONVERSION */
-
-#include "jsimd_mmi.h"
-
-
-#define F_0_344  ((short)22554)  /* FIX(0.34414) */
-#define F_0_402  ((short)26345)  /* FIX(1.40200) - FIX(1) */
-#define F_0_285  ((short)18734)  /* FIX(1) - FIX(0.71414) */
-#define F_0_228  ((short)14942)  /* FIX(2) - FIX(1.77200) */
-
-enum const_index {
-  index_PW_ONE,
-  index_PW_F0402,
-  index_PW_MF0228,
-  index_PW_MF0344_F0285,
-  index_PD_ONEHALF
-};
-
-static uint64_t const_value[] = {
-  _uint64_set_pi16(1, 1, 1, 1),
-  _uint64_set_pi16(F_0_402, F_0_402, F_0_402, F_0_402),
-  _uint64_set_pi16(-F_0_228, -F_0_228, -F_0_228, -F_0_228),
-  _uint64_set_pi16(F_0_285, -F_0_344, F_0_285, -F_0_344),
-  _uint64_set_pi32((int)(1 << (SCALEBITS - 1)), (int)(1 << (SCALEBITS - 1)))
-};
-
-#define PW_ONE           get_const_value(index_PW_ONE)
-#define PW_F0402         get_const_value(index_PW_F0402)
-#define PW_MF0228        get_const_value(index_PW_MF0228)
-#define PW_MF0344_F0285  get_const_value(index_PW_MF0344_F0285)
-#define PD_ONEHALF       get_const_value(index_PD_ONEHALF)
-
-#define RGBX_FILLER_0XFF  1
-
-
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-
-#define RGB_RED  EXT_RGB_RED
-#define RGB_GREEN  EXT_RGB_GREEN
-#define RGB_BLUE  EXT_RGB_BLUE
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extrgb_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
-
-#define RGB_RED  EXT_RGBX_RED
-#define RGB_GREEN  EXT_RGBX_GREEN
-#define RGB_BLUE  EXT_RGBX_BLUE
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extrgbx_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
-
-#define RGB_RED  EXT_BGR_RED
-#define RGB_GREEN  EXT_BGR_GREEN
-#define RGB_BLUE  EXT_BGR_BLUE
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extbgr_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
-
-#define RGB_RED  EXT_BGRX_RED
-#define RGB_GREEN  EXT_BGRX_GREEN
-#define RGB_BLUE  EXT_BGRX_BLUE
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extbgrx_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
-
-#define RGB_RED  EXT_XBGR_RED
-#define RGB_GREEN  EXT_XBGR_GREEN
-#define RGB_BLUE  EXT_XBGR_BLUE
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extxbgr_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
-
-#define RGB_RED  EXT_XRGB_RED
-#define RGB_GREEN  EXT_XRGB_GREEN
-#define RGB_BLUE  EXT_XRGB_BLUE
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define jsimd_ycc_rgb_convert_mmi  jsimd_ycc_extxrgb_convert_mmi
-#include "jdcolext-mmi.c"
-#undef RGB_RED
-#undef RGB_GREEN
-#undef RGB_BLUE
-#undef RGB_PIXELSIZE
-#undef jsimd_ycc_rgb_convert_mmi
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jdsample-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jdsample-mmi.c
deleted file mode 100644
index 00a6265..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jdsample-mmi.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, 2018, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* CHROMA UPSAMPLING */
-
-#include "jsimd_mmi.h"
-
-
-enum const_index {
-  index_PW_THREE,
-  index_PW_SEVEN,
-  index_PW_EIGHT,
-};
-
-static uint64_t const_value[] = {
-  _uint64_set_pi16(3, 3, 3, 3),
-  _uint64_set_pi16(7, 7, 7, 7),
-  _uint64_set_pi16(8, 8, 8, 8),
-};
-
-#define PW_THREE  get_const_value(index_PW_THREE)
-#define PW_SEVEN  get_const_value(index_PW_SEVEN)
-#define PW_EIGHT  get_const_value(index_PW_EIGHT)
-
-
-#define PROCESS_ROW(r) { \
-  mm7 = _mm_load_si64((__m64 *)outptr##r);      /* mm7=IntrL=( 0 1 2 3) */ \
-  mm3 = _mm_load_si64((__m64 *)outptr##r + 1);  /* mm3=IntrH=( 4 5 6 7) */ \
-  \
-  mm0 = mm7; \
-  mm4 = mm3; \
-  mm0 = _mm_srli_si64(mm0, 2 * BYTE_BIT);                   /* mm0=( 1 2 3 -) */ \
-  mm4 = _mm_slli_si64(mm4, (SIZEOF_MMWORD - 2) * BYTE_BIT); /* mm4=( - - - 4) */ \
-  mm5 = mm7; \
-  mm6 = mm3; \
-  mm5 = _mm_srli_si64(mm5, (SIZEOF_MMWORD - 2) * BYTE_BIT); /* mm5=( 3 - - -) */ \
-  mm6 = _mm_slli_si64(mm6, 2 * BYTE_BIT);                   /* mm6=( - 4 5 6) */ \
-  \
-  mm0 = _mm_or_si64(mm0, mm4);                /* mm0=( 1 2 3 4) */ \
-  mm5 = _mm_or_si64(mm5, mm6);                /* mm5=( 3 4 5 6) */ \
-  \
-  mm1 = mm7; \
-  mm2 = mm3; \
-  mm1 = _mm_slli_si64(mm1, 2 * BYTE_BIT);     /* mm1=( - 0 1 2) */ \
-  mm2 = _mm_srli_si64(mm2, 2 * BYTE_BIT);     /* mm2=( 5 6 7 -) */ \
-  mm4 = mm3; \
-  mm4 = _mm_srli_si64(mm4, (SIZEOF_MMWORD - 2) * BYTE_BIT); /* mm4=( 7 - - -) */ \
-  \
-  mm1 = _mm_or_si64(mm1, wk[r]);              /* mm1=(-1 0 1 2) */ \
-  mm2 = _mm_or_si64(mm2, wk[r + 2]);          /* mm2=( 5 6 6 8) */ \
-  \
-  wk[r] = mm4; \
-  \
-  mm7 = _mm_mullo_pi16(mm7, PW_THREE); \
-  mm3 = _mm_mullo_pi16(mm3, PW_THREE); \
-  mm1 = _mm_add_pi16(mm1, PW_EIGHT); \
-  mm5 = _mm_add_pi16(mm5, PW_EIGHT); \
-  mm0 = _mm_add_pi16(mm0, PW_SEVEN); \
-  mm2 = _mm_add_pi16(mm2, PW_SEVEN); \
-  \
-  mm1 = _mm_add_pi16(mm1, mm7); \
-  mm5 = _mm_add_pi16(mm5, mm3); \
-  mm1 = _mm_srli_pi16(mm1, 4);                /* mm1=OutrLE=( 0  2  4  6) */ \
-  mm5 = _mm_srli_pi16(mm5, 4);                /* mm5=OutrHE=( 8 10 12 14) */ \
-  mm0 = _mm_add_pi16(mm0, mm7); \
-  mm2 = _mm_add_pi16(mm2, mm3); \
-  mm0 = _mm_srli_pi16(mm0, 4);                /* mm0=OutrLO=( 1  3  5  7) */ \
-  mm2 = _mm_srli_pi16(mm2, 4);                /* mm2=OutrHO=( 9 11 13 15) */ \
-  \
-  mm0 = _mm_slli_pi16(mm0, BYTE_BIT); \
-  mm2 = _mm_slli_pi16(mm2, BYTE_BIT); \
-  mm1 = _mm_or_si64(mm1, mm0);     /* mm1=OutrL=( 0  1  2  3  4  5  6  7) */ \
-  mm5 = _mm_or_si64(mm5, mm2);     /* mm5=OutrH=( 8  9 10 11 12 13 14 15) */ \
-  \
-  _mm_store_si64((__m64 *)outptr##r, mm1); \
-  _mm_store_si64((__m64 *)outptr##r + 1, mm5); \
-}
-
-void jsimd_h2v2_fancy_upsample_mmi(int max_v_samp_factor,
-                                   JDIMENSION downsampled_width,
-                                   JSAMPARRAY input_data,
-                                   JSAMPARRAY *output_data_ptr)
-{
-  JSAMPARRAY output_data = *output_data_ptr;
-  JSAMPROW inptr_1, inptr0, inptr1, outptr0, outptr1;
-  int inrow, outrow, incol, tmp, tmp1;
-  __m64 mm0, mm1, mm2, mm3 = 0.0, mm4, mm5, mm6, mm7 = 0.0;
-  __m64 wk[4], mm_tmp;
-
-  for (inrow = 0, outrow = 0; outrow < max_v_samp_factor; inrow++) {
-
-    inptr_1 = input_data[inrow - 1];
-    inptr0 = input_data[inrow];
-    inptr1 = input_data[inrow + 1];
-    outptr0 = output_data[outrow++];
-    outptr1 = output_data[outrow++];
-
-    if (downsampled_width & 7) {
-      tmp = (downsampled_width - 1) * sizeof(JSAMPLE);
-      tmp1 =  downsampled_width * sizeof(JSAMPLE);
-      asm("daddu  $8, %3, %6\r\n"
-          "lb     $9, ($8)\r\n"
-          "daddu  $8, %3, %7\r\n"
-          "sb     $9, ($8)\r\n"
-          "daddu  $8, %4, %6\r\n"
-          "lb     $9, ($8)\r\n"
-          "daddu  $8, %4, %7\r\n"
-          "sb     $9, ($8)\r\n"
-          "daddu  $8, %5, %6\r\n"
-          "lb     $9, ($8)\r\n"
-          "daddu  $8, %5, %7\r\n"
-          "sb     $9, ($8)\r\n"
-          : "=m" (*inptr_1), "=m" (*inptr0), "=m" (*inptr1)
-          : "r" (inptr_1), "r" (inptr0), "r" (inptr1), "r" (tmp), "r" (tmp1)
-          : "$8", "$9"
-         );
-    }
-
-    /* process the first column block */
-    mm0 = _mm_load_si64((__m64 *)inptr0);     /* mm0 = row[ 0][0] */
-    mm1 = _mm_load_si64((__m64 *)inptr_1);    /* mm1 = row[-1][0] */
-    mm2 = _mm_load_si64((__m64 *)inptr1);     /* mm2 = row[ 1][0] */
-
-    mm3 = _mm_xor_si64(mm3, mm3);             /* mm3 = (all 0's) */
-    mm4 = mm0;
-    mm0 = _mm_unpacklo_pi8(mm0, mm3);         /* mm0 = row[ 0][0]( 0 1 2 3) */
-    mm4 = _mm_unpackhi_pi8(mm4, mm3);         /* mm4 = row[ 0][0]( 4 5 6 7) */
-    mm5 = mm1;
-    mm1 = _mm_unpacklo_pi8(mm1, mm3);         /* mm1 = row[-1][0]( 0 1 2 3) */
-    mm5 = _mm_unpackhi_pi8(mm5, mm3);         /* mm5 = row[-1][0]( 4 5 6 7) */
-    mm6 = mm2;
-    mm2 = _mm_unpacklo_pi8(mm2, mm3);         /* mm2 = row[+1][0]( 0 1 2 3) */
-    mm6 = _mm_unpackhi_pi8(mm6, mm3);         /* mm6 = row[+1][0]( 4 5 6 7) */
-
-    mm0 = _mm_mullo_pi16(mm0, PW_THREE);
-    mm4 = _mm_mullo_pi16(mm4, PW_THREE);
-
-    mm7 = _mm_cmpeq_pi8(mm7, mm7);
-    mm7 = _mm_srli_si64(mm7, (SIZEOF_MMWORD - 2) * BYTE_BIT);
-
-    mm1 = _mm_add_pi16(mm1, mm0);             /* mm1=Int0L=( 0 1 2 3) */
-    mm5 = _mm_add_pi16(mm5, mm4);             /* mm5=Int0H=( 4 5 6 7) */
-    mm2 = _mm_add_pi16(mm2, mm0);             /* mm2=Int1L=( 0 1 2 3) */
-    mm6 = _mm_add_pi16(mm6, mm4);             /* mm6=Int1H=( 4 5 6 7) */
-
-    _mm_store_si64((__m64 *)outptr0, mm1);      /* temporarily save */
-    _mm_store_si64((__m64 *)outptr0 + 1, mm5);  /* the intermediate data */
-    _mm_store_si64((__m64 *)outptr1, mm2);
-    _mm_store_si64((__m64 *)outptr1 + 1, mm6);
-
-    mm1 = _mm_and_si64(mm1, mm7);             /* mm1=( 0 - - -) */
-    mm2 = _mm_and_si64(mm2, mm7);             /* mm2=( 0 - - -) */
-
-    wk[0] = mm1;
-    wk[1] = mm2;
-
-    for (incol = downsampled_width; incol > 0;
-         incol -= 8, inptr_1 += 8, inptr0 += 8, inptr1 += 8,
-         outptr0 += 16, outptr1 += 16) {
-
-      if (incol > 8) {
-        /* process the next column block */
-        mm0 = _mm_load_si64((__m64 *)inptr0 + 1);   /* mm0 = row[ 0][1] */
-        mm1 = _mm_load_si64((__m64 *)inptr_1 + 1);  /* mm1 = row[-1][1] */
-        mm2 = _mm_load_si64((__m64 *)inptr1 + 1);   /* mm2 = row[+1][1] */
-
-        mm3 = _mm_setzero_si64();             /* mm3 = (all 0's) */
-        mm4 = mm0;
-        mm0 = _mm_unpacklo_pi8(mm0, mm3);     /* mm0 = row[ 0][1]( 0 1 2 3) */
-        mm4 = _mm_unpackhi_pi8(mm4, mm3);     /* mm4 = row[ 0][1]( 4 5 6 7) */
-        mm5 = mm1;
-        mm1 = _mm_unpacklo_pi8(mm1, mm3);     /* mm1 = row[-1][1]( 0 1 2 3) */
-        mm5 = _mm_unpackhi_pi8(mm5, mm3);     /* mm5 = row[-1][1]( 4 5 6 7) */
-        mm6 = mm2;
-        mm2 = _mm_unpacklo_pi8(mm2, mm3);     /* mm2 = row[+1][1]( 0 1 2 3) */
-        mm6 = _mm_unpackhi_pi8(mm6, mm3);     /* mm6 = row[+1][1]( 4 5 6 7) */
-
-        mm0 = _mm_mullo_pi16(mm0, PW_THREE);
-        mm4 = _mm_mullo_pi16(mm4, PW_THREE);
-
-        mm1 = _mm_add_pi16(mm1, mm0);         /* mm1 = Int0L = ( 0 1 2 3) */
-        mm5 = _mm_add_pi16(mm5, mm4);         /* mm5 = Int0H = ( 4 5 6 7) */
-        mm2 = _mm_add_pi16(mm2, mm0);         /* mm2 = Int1L = ( 0 1 2 3) */
-        mm6 = _mm_add_pi16(mm6, mm4);         /* mm6 = Int1H = ( 4 5 6 7) */
-
-        _mm_store_si64((__m64 *)outptr0 + 2, mm1);  /* temporarily save */
-        _mm_store_si64((__m64 *)outptr0 + 3, mm5);  /* the intermediate data */
-        _mm_store_si64((__m64 *)outptr1 + 2, mm2);
-        _mm_store_si64((__m64 *)outptr1 + 3, mm6);
-
-        mm1 = _mm_slli_si64(mm1, (SIZEOF_MMWORD - 2) * BYTE_BIT); /* mm1=( - - - 0) */
-        mm2 = _mm_slli_si64(mm2, (SIZEOF_MMWORD - 2) * BYTE_BIT); /* mm2=( - - - 0) */
-
-        wk[2] = mm1;
-        wk[3] = mm2;
-      } else {
-        /* process the last column block */
-        mm1 = _mm_cmpeq_pi8(mm1, mm1);
-        mm1 = _mm_slli_si64(mm1, (SIZEOF_MMWORD - 2) * BYTE_BIT);
-        mm2 = mm1;
-
-        mm_tmp = _mm_load_si64((__m64 *)outptr0 + 1);
-        mm1 = _mm_and_si64(mm1, mm_tmp);      /* mm1=( - - - 7) */
-        mm_tmp = _mm_load_si64((__m64 *)outptr1 + 1);
-        mm2 = _mm_and_si64(mm2, mm_tmp);      /* mm2=( - - - 7) */
-
-        wk[2] = mm1;
-        wk[3] = mm2;
-      }
-
-      /* process the upper row */
-      PROCESS_ROW(0)
-
-      /* process the lower row */
-      PROCESS_ROW(1)
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jfdctint-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jfdctint-mmi.c
deleted file mode 100644
index a0ea692..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jfdctint-mmi.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014, 2018, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* SLOW INTEGER FORWARD DCT */
-
-#include "jsimd_mmi.h"
-
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
-#define DESCALE_P2  (CONST_BITS + PASS1_BITS)
-
-#define FIX_0_298  ((short)2446)   /* FIX(0.298631336) */
-#define FIX_0_390  ((short)3196)   /* FIX(0.390180644) */
-#define FIX_0_541  ((short)4433)   /* FIX(0.541196100) */
-#define FIX_0_765  ((short)6270)   /* FIX(0.765366865) */
-#define FIX_0_899  ((short)7373)   /* FIX(0.899976223) */
-#define FIX_1_175  ((short)9633)   /* FIX(1.175875602) */
-#define FIX_1_501  ((short)12299)  /* FIX(1.501321110) */
-#define FIX_1_847  ((short)15137)  /* FIX(1.847759065) */
-#define FIX_1_961  ((short)16069)  /* FIX(1.961570560) */
-#define FIX_2_053  ((short)16819)  /* FIX(2.053119869) */
-#define FIX_2_562  ((short)20995)  /* FIX(2.562915447) */
-#define FIX_3_072  ((short)25172)  /* FIX(3.072711026) */
-
-enum const_index {
-  index_PW_F130_F054,
-  index_PW_F054_MF130,
-  index_PW_MF078_F117,
-  index_PW_F117_F078,
-  index_PW_MF060_MF089,
-  index_PW_MF089_F060,
-  index_PW_MF050_MF256,
-  index_PW_MF256_F050,
-  index_PD_DESCALE_P1,
-  index_PD_DESCALE_P2,
-  index_PW_DESCALE_P2X
-};
-
-static uint64_t const_value[] = {
-  _uint64_set_pi16(FIX_0_541, (FIX_0_541 + FIX_0_765),
-                   FIX_0_541, (FIX_0_541 + FIX_0_765)),
-  _uint64_set_pi16((FIX_0_541 - FIX_1_847), FIX_0_541,
-                   (FIX_0_541 - FIX_1_847), FIX_0_541),
-  _uint64_set_pi16(FIX_1_175, (FIX_1_175 - FIX_1_961),
-                   FIX_1_175, (FIX_1_175 - FIX_1_961)),
-  _uint64_set_pi16((FIX_1_175 - FIX_0_390), FIX_1_175,
-                   (FIX_1_175 - FIX_0_390), FIX_1_175),
-  _uint64_set_pi16(-FIX_0_899, (FIX_0_298 - FIX_0_899),
-                   -FIX_0_899, (FIX_0_298 - FIX_0_899)),
-  _uint64_set_pi16((FIX_1_501 - FIX_0_899), -FIX_0_899,
-                   (FIX_1_501 - FIX_0_899), -FIX_0_899),
-  _uint64_set_pi16(-FIX_2_562, (FIX_2_053 - FIX_2_562),
-                   -FIX_2_562, (FIX_2_053 - FIX_2_562)),
-  _uint64_set_pi16((FIX_3_072 - FIX_2_562), -FIX_2_562,
-                   (FIX_3_072 - FIX_2_562), -FIX_2_562),
-  _uint64_set_pi32((1 << (DESCALE_P1 - 1)), (1 << (DESCALE_P1 - 1))),
-  _uint64_set_pi32((1 << (DESCALE_P2 - 1)), (1 << (DESCALE_P2 - 1))),
-  _uint64_set_pi16((1 << (PASS1_BITS - 1)), (1 << (PASS1_BITS - 1)),
-                   (1 << (PASS1_BITS - 1)), (1 << (PASS1_BITS - 1)))
-};
-
-#define PW_F130_F054    get_const_value(index_PW_F130_F054)
-#define PW_F054_MF130   get_const_value(index_PW_F054_MF130)
-#define PW_MF078_F117   get_const_value(index_PW_MF078_F117)
-#define PW_F117_F078    get_const_value(index_PW_F117_F078)
-#define PW_MF060_MF089  get_const_value(index_PW_MF060_MF089)
-#define PW_MF089_F060   get_const_value(index_PW_MF089_F060)
-#define PW_MF050_MF256  get_const_value(index_PW_MF050_MF256)
-#define PW_MF256_F050   get_const_value(index_PW_MF256_F050)
-#define PD_DESCALE_P1   get_const_value(index_PD_DESCALE_P1)
-#define PD_DESCALE_P2   get_const_value(index_PD_DESCALE_P2)
-#define PW_DESCALE_P2X  get_const_value(index_PW_DESCALE_P2X)
-
-
-#define DO_FDCT_COMMON(PASS) { \
-  __m64 tmp1312l, tmp1312h, tmp47l, tmp47h, tmp4l, tmp4h, tmp7l, tmp7h; \
-  __m64 tmp56l, tmp56h, tmp5l, tmp5h, tmp6l, tmp6h; \
-  __m64 out1l, out1h, out2l, out2h, out3l, out3h; \
-  __m64 out5l, out5h, out6l, out6h, out7l, out7h; \
-  __m64 z34l, z34h, z3l, z3h, z4l, z4h, z3, z4; \
-  \
-  /* (Original) \
-   * z1 = (tmp12 + tmp13) * 0.541196100; \
-   * out2 = z1 + tmp13 * 0.765366865; \
-   * out6 = z1 + tmp12 * -1.847759065; \
-   * \
-   * (This implementation) \
-   * out2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100; \
-   * out6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065); \
-   */ \
-  \
-  tmp1312l = _mm_unpacklo_pi16(tmp13, tmp12); \
-  tmp1312h = _mm_unpackhi_pi16(tmp13, tmp12); \
-  \
-  out2l = _mm_madd_pi16(tmp1312l, PW_F130_F054); \
-  out2h = _mm_madd_pi16(tmp1312h, PW_F130_F054); \
-  out6l = _mm_madd_pi16(tmp1312l, PW_F054_MF130); \
-  out6h = _mm_madd_pi16(tmp1312h, PW_F054_MF130); \
-  \
-  out2l = _mm_add_pi32(out2l, PD_DESCALE_P##PASS); \
-  out2h = _mm_add_pi32(out2h, PD_DESCALE_P##PASS); \
-  out2l = _mm_srai_pi32(out2l, DESCALE_P##PASS); \
-  out2h = _mm_srai_pi32(out2h, DESCALE_P##PASS); \
-  \
-  out6l = _mm_add_pi32(out6l, PD_DESCALE_P##PASS); \
-  out6h = _mm_add_pi32(out6h, PD_DESCALE_P##PASS); \
-  out6l = _mm_srai_pi32(out6l, DESCALE_P##PASS); \
-  out6h = _mm_srai_pi32(out6h, DESCALE_P##PASS); \
-  \
-  out2 = _mm_packs_pi32(out2l, out2h); \
-  out6 = _mm_packs_pi32(out6l, out6h); \
-  \
-  /* Odd part */ \
-  \
-  z3 = _mm_add_pi16(tmp4, tmp6); \
-  z4 = _mm_add_pi16(tmp5, tmp7); \
-  \
-  /* (Original) \
-   * z5 = (z3 + z4) * 1.175875602; \
-   * z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644; \
-   * z3 += z5;  z4 += z5; \
-   * \
-   * (This implementation) \
-   * z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602; \
-   * z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644); \
-   */ \
-  \
-  z34l = _mm_unpacklo_pi16(z3, z4); \
-  z34h = _mm_unpackhi_pi16(z3, z4); \
-  z3l = _mm_madd_pi16(z34l, PW_MF078_F117); \
-  z3h = _mm_madd_pi16(z34h, PW_MF078_F117); \
-  z4l = _mm_madd_pi16(z34l, PW_F117_F078); \
-  z4h = _mm_madd_pi16(z34h, PW_F117_F078); \
-  \
-  /* (Original) \
-   * z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6; \
-   * tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869; \
-   * tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110; \
-   * z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447; \
-   * out7 = tmp4 + z1 + z3;  out5 = tmp5 + z2 + z4; \
-   * out3 = tmp6 + z2 + z3;  out1 = tmp7 + z1 + z4; \
-   * \
-   * (This implementation) \
-   * tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223; \
-   * tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447; \
-   * tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447); \
-   * tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223); \
-   * out7 = tmp4 + z3;  out5 = tmp5 + z4; \
-   * out3 = tmp6 + z3;  out1 = tmp7 + z4; \
-   */ \
-  \
-  tmp47l = _mm_unpacklo_pi16(tmp4, tmp7); \
-  tmp47h = _mm_unpackhi_pi16(tmp4, tmp7); \
-  \
-  tmp4l = _mm_madd_pi16(tmp47l, PW_MF060_MF089); \
-  tmp4h = _mm_madd_pi16(tmp47h, PW_MF060_MF089); \
-  tmp7l = _mm_madd_pi16(tmp47l, PW_MF089_F060); \
-  tmp7h = _mm_madd_pi16(tmp47h, PW_MF089_F060); \
-  \
-  out7l = _mm_add_pi32(tmp4l, z3l); \
-  out7h = _mm_add_pi32(tmp4h, z3h); \
-  out1l = _mm_add_pi32(tmp7l, z4l); \
-  out1h = _mm_add_pi32(tmp7h, z4h); \
-  \
-  out7l = _mm_add_pi32(out7l, PD_DESCALE_P##PASS); \
-  out7h = _mm_add_pi32(out7h, PD_DESCALE_P##PASS); \
-  out7l = _mm_srai_pi32(out7l, DESCALE_P##PASS); \
-  out7h = _mm_srai_pi32(out7h, DESCALE_P##PASS); \
-  \
-  out1l = _mm_add_pi32(out1l, PD_DESCALE_P##PASS); \
-  out1h = _mm_add_pi32(out1h, PD_DESCALE_P##PASS); \
-  out1l = _mm_srai_pi32(out1l, DESCALE_P##PASS); \
-  out1h = _mm_srai_pi32(out1h, DESCALE_P##PASS); \
-  \
-  out7 = _mm_packs_pi32(out7l, out7h); \
-  out1 = _mm_packs_pi32(out1l, out1h); \
-  \
-  tmp56l = _mm_unpacklo_pi16(tmp5, tmp6); \
-  tmp56h = _mm_unpackhi_pi16(tmp5, tmp6); \
-  \
-  tmp5l = _mm_madd_pi16(tmp56l, PW_MF050_MF256); \
-  tmp5h = _mm_madd_pi16(tmp56h, PW_MF050_MF256); \
-  tmp6l = _mm_madd_pi16(tmp56l, PW_MF256_F050); \
-  tmp6h = _mm_madd_pi16(tmp56h, PW_MF256_F050); \
-  \
-  out5l = _mm_add_pi32(tmp5l, z4l); \
-  out5h = _mm_add_pi32(tmp5h, z4h); \
-  out3l = _mm_add_pi32(tmp6l, z3l); \
-  out3h = _mm_add_pi32(tmp6h, z3h); \
-  \
-  out5l = _mm_add_pi32(out5l, PD_DESCALE_P##PASS); \
-  out5h = _mm_add_pi32(out5h, PD_DESCALE_P##PASS); \
-  out5l = _mm_srai_pi32(out5l, DESCALE_P##PASS); \
-  out5h = _mm_srai_pi32(out5h, DESCALE_P##PASS); \
-  \
-  out3l = _mm_add_pi32(out3l, PD_DESCALE_P##PASS); \
-  out3h = _mm_add_pi32(out3h, PD_DESCALE_P##PASS); \
-  out3l = _mm_srai_pi32(out3l, DESCALE_P##PASS); \
-  out3h = _mm_srai_pi32(out3h, DESCALE_P##PASS); \
-  \
-  out5 = _mm_packs_pi32(out5l, out5h); \
-  out3 = _mm_packs_pi32(out3l, out3h); \
-}
-
-#define DO_FDCT_PASS1() { \
-  __m64 row0l, row0h, row1l, row1h, row2l, row2h, row3l, row3h; \
-  __m64 row01a, row01b, row01c, row01d, row23a, row23b, row23c, row23d; \
-  __m64 col0, col1, col2, col3, col4, col5, col6, col7; \
-  __m64 tmp10, tmp11; \
-  \
-  row0l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 0]);     /* (00 01 02 03) */ \
-  row0h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 0 + 4]); /* (04 05 06 07) */ \
-  row1l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 1]);     /* (10 11 12 13) */ \
-  row1h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 1 + 4]); /* (14 15 16 17) */ \
-  row2l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 2]);     /* (20 21 22 23) */ \
-  row2h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 2 + 4]); /* (24 25 26 27) */ \
-  row3l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 3]);     /* (30 31 32 33) */ \
-  row3h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 3 + 4]); /* (34 35 36 37) */ \
-  \
-  /* Transpose coefficients */ \
-  \
-  row23a = _mm_unpacklo_pi16(row2l, row3l);   /* row23a=(20 30 21 31) */ \
-  row23b = _mm_unpackhi_pi16(row2l, row3l);   /* row23b=(22 32 23 33) */ \
-  row23c = _mm_unpacklo_pi16(row2h, row3h);   /* row23c=(24 34 25 35) */ \
-  row23d = _mm_unpackhi_pi16(row2h, row3h);   /* row23d=(26 36 27 37) */ \
-  \
-  row01a = _mm_unpacklo_pi16(row0l, row1l);   /* row01a=(00 10 01 11) */ \
-  row01b = _mm_unpackhi_pi16(row0l, row1l);   /* row01b=(02 12 03 13) */ \
-  row01c = _mm_unpacklo_pi16(row0h, row1h);   /* row01c=(04 14 05 15) */ \
-  row01d = _mm_unpackhi_pi16(row0h, row1h);   /* row01d=(06 16 07 17) */ \
-  \
-  col0 = _mm_unpacklo_pi32(row01a, row23a);   /* col0=(00 10 20 30) */ \
-  col1 = _mm_unpackhi_pi32(row01a, row23a);   /* col1=(01 11 21 31) */ \
-  col6 = _mm_unpacklo_pi32(row01d, row23d);   /* col6=(06 16 26 36) */ \
-  col7 = _mm_unpackhi_pi32(row01d, row23d);   /* col7=(07 17 27 37) */ \
-  \
-  tmp6 = _mm_sub_pi16(col1, col6);            /* tmp6=col1-col6 */ \
-  tmp7 = _mm_sub_pi16(col0, col7);            /* tmp7=col0-col7 */ \
-  tmp1 = _mm_add_pi16(col1, col6);            /* tmp1=col1+col6 */ \
-  tmp0 = _mm_add_pi16(col0, col7);            /* tmp0=col0+col7 */ \
-  \
-  col2 = _mm_unpacklo_pi32(row01b, row23b);   /* col2=(02 12 22 32) */ \
-  col3 = _mm_unpackhi_pi32(row01b, row23b);   /* col3=(03 13 23 33) */ \
-  col4 = _mm_unpacklo_pi32(row01c, row23c);   /* col4=(04 14 24 34) */ \
-  col5 = _mm_unpackhi_pi32(row01c, row23c);   /* col5=(05 15 25 35) */ \
-  \
-  tmp3 = _mm_add_pi16(col3, col4);            /* tmp3=col3+col4 */ \
-  tmp2 = _mm_add_pi16(col2, col5);            /* tmp2=col2+col5 */ \
-  tmp4 = _mm_sub_pi16(col3, col4);            /* tmp4=col3-col4 */ \
-  tmp5 = _mm_sub_pi16(col2, col5);            /* tmp5=col2-col5 */ \
-  \
-  /* Even part */ \
-  \
-  tmp10 = _mm_add_pi16(tmp0, tmp3);           /* tmp10=tmp0+tmp3 */ \
-  tmp13 = _mm_sub_pi16(tmp0, tmp3);           /* tmp13=tmp0-tmp3 */ \
-  tmp11 = _mm_add_pi16(tmp1, tmp2);           /* tmp11=tmp1+tmp2 */ \
-  tmp12 = _mm_sub_pi16(tmp1, tmp2);           /* tmp12=tmp1-tmp2 */ \
-  \
-  out0 = _mm_add_pi16(tmp10, tmp11);          /* out0=tmp10+tmp11 */ \
-  out4 = _mm_sub_pi16(tmp10, tmp11);          /* out4=tmp10-tmp11 */ \
-  out0 = _mm_slli_pi16(out0, PASS1_BITS); \
-  out4 = _mm_slli_pi16(out4, PASS1_BITS); \
-  \
-  DO_FDCT_COMMON(1) \
-  \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 0], out0); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 0 + 4], out4); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 1], out1); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 1 + 4], out5); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 2], out2); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 2 + 4], out6); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 3], out3); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 3 + 4], out7); \
-}
-
-#define DO_FDCT_PASS2() { \
-  __m64 col0l, col0h, col1l, col1h, col2l, col2h, col3l, col3h; \
-  __m64 col01a, col01b, col01c, col01d, col23a, col23b, col23c, col23d; \
-  __m64 row0, row1, row2, row3, row4, row5, row6, row7; \
-  __m64 tmp10, tmp11; \
-  \
-  col0l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 0]);  /* (00 10 20 30) */ \
-  col1l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 1]);  /* (01 11 21 31) */ \
-  col2l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 2]);  /* (02 12 22 32) */ \
-  col3l = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 3]);  /* (03 13 23 33) */ \
-  col0h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 4]);  /* (40 50 60 70) */ \
-  col1h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 5]);  /* (41 51 61 71) */ \
-  col2h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 6]);  /* (42 52 62 72) */ \
-  col3h = _mm_load_si64((__m64 *)&dataptr[DCTSIZE * 7]);  /* (43 53 63 73) */ \
-  \
-  /* Transpose coefficients */ \
-  \
-  col23a = _mm_unpacklo_pi16(col2l, col3l);   /* col23a=(02 03 12 13) */ \
-  col23b = _mm_unpackhi_pi16(col2l, col3l);   /* col23b=(22 23 32 33) */ \
-  col23c = _mm_unpacklo_pi16(col2h, col3h);   /* col23c=(42 43 52 53) */ \
-  col23d = _mm_unpackhi_pi16(col2h, col3h);   /* col23d=(62 63 72 73) */ \
-  \
-  col01a = _mm_unpacklo_pi16(col0l, col1l);   /* col01a=(00 01 10 11) */ \
-  col01b = _mm_unpackhi_pi16(col0l, col1l);   /* col01b=(20 21 30 31) */ \
-  col01c = _mm_unpacklo_pi16(col0h, col1h);   /* col01c=(40 41 50 51) */ \
-  col01d = _mm_unpackhi_pi16(col0h, col1h);   /* col01d=(60 61 70 71) */ \
-  \
-  row0 = _mm_unpacklo_pi32(col01a, col23a);   /* row0=(00 01 02 03) */ \
-  row1 = _mm_unpackhi_pi32(col01a, col23a);   /* row1=(10 11 12 13) */ \
-  row6 = _mm_unpacklo_pi32(col01d, col23d);   /* row6=(60 61 62 63) */ \
-  row7 = _mm_unpackhi_pi32(col01d, col23d);   /* row7=(70 71 72 73) */ \
-  \
-  tmp6 = _mm_sub_pi16(row1, row6);            /* tmp6=row1-row6 */ \
-  tmp7 = _mm_sub_pi16(row0, row7);            /* tmp7=row0-row7 */ \
-  tmp1 = _mm_add_pi16(row1, row6);            /* tmp1=row1+row6 */ \
-  tmp0 = _mm_add_pi16(row0, row7);            /* tmp0=row0+row7 */ \
-  \
-  row2 = _mm_unpacklo_pi32(col01b, col23b);   /* row2=(20 21 22 23) */ \
-  row3 = _mm_unpackhi_pi32(col01b, col23b);   /* row3=(30 31 32 33) */ \
-  row4 = _mm_unpacklo_pi32(col01c, col23c);   /* row4=(40 41 42 43) */ \
-  row5 = _mm_unpackhi_pi32(col01c, col23c);   /* row5=(50 51 52 53) */ \
-  \
-  tmp3 = _mm_add_pi16(row3, row4);            /* tmp3=row3+row4 */ \
-  tmp2 = _mm_add_pi16(row2, row5);            /* tmp2=row2+row5 */ \
-  tmp4 = _mm_sub_pi16(row3, row4);            /* tmp4=row3-row4 */ \
-  tmp5 = _mm_sub_pi16(row2, row5);            /* tmp5=row2-row5 */ \
-  \
-  /* Even part */ \
-  \
-  tmp10 = _mm_add_pi16(tmp0, tmp3);           /* tmp10=tmp0+tmp3 */ \
-  tmp13 = _mm_sub_pi16(tmp0, tmp3);           /* tmp13=tmp0-tmp3 */ \
-  tmp11 = _mm_add_pi16(tmp1, tmp2);           /* tmp11=tmp1+tmp2 */ \
-  tmp12 = _mm_sub_pi16(tmp1, tmp2);           /* tmp12=tmp1-tmp2 */ \
-  \
-  out0 = _mm_add_pi16(tmp10, tmp11);          /* out0=tmp10+tmp11 */ \
-  out4 = _mm_sub_pi16(tmp10, tmp11);          /* out4=tmp10-tmp11 */ \
-  \
-  out0 = _mm_add_pi16(out0, PW_DESCALE_P2X); \
-  out4 = _mm_add_pi16(out4, PW_DESCALE_P2X); \
-  out0 = _mm_srai_pi16(out0, PASS1_BITS); \
-  out4 = _mm_srai_pi16(out4, PASS1_BITS); \
-  \
-  DO_FDCT_COMMON(2) \
-  \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 0], out0); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 1], out1); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 2], out2); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 3], out3); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 4], out4); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 5], out5); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 6], out6); \
-  _mm_store_si64((__m64 *)&dataptr[DCTSIZE * 7], out7); \
-}
-
-void jsimd_fdct_islow_mmi(DCTELEM *data)
-{
-  __m64 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
-  __m64 out0, out1, out2, out3, out4, out5, out6, out7;
-  __m64 tmp12, tmp13;
-  DCTELEM *dataptr = data;
-
-  /* Pass 1: process rows. */
-
-  DO_FDCT_PASS1()
-  dataptr += DCTSIZE * 4;
-  DO_FDCT_PASS1()
-
-  /* Pass 2: process columns. */
-
-  dataptr = data;
-  DO_FDCT_PASS2()
-  dataptr += 4;
-  DO_FDCT_PASS2()
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jidctint-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jidctint-mmi.c
deleted file mode 100644
index 419c638..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jidctint-mmi.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, 2018, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* SLOW INTEGER INVERSE DCT */
-
-#include "jsimd_mmi.h"
-
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
-#define DESCALE_P2  (CONST_BITS + PASS1_BITS + 3)
-#define CENTERJSAMPLE  128
-
-#define FIX_0_298  ((short)2446)  /* FIX(0.298631336) */
-#define FIX_0_390  ((short)3196)  /* FIX(0.390180644) */
-#define FIX_0_899  ((short)7373)  /* FIX(0.899976223) */
-#define FIX_0_541  ((short)4433)  /* FIX(0.541196100) */
-#define FIX_0_765  ((short)6270)  /* FIX(0.765366865) */
-#define FIX_1_175  ((short)9633)  /* FIX(1.175875602) */
-#define FIX_1_501  ((short)12299) /* FIX(1.501321110) */
-#define FIX_1_847  ((short)15137) /* FIX(1.847759065) */
-#define FIX_1_961  ((short)16069) /* FIX(1.961570560) */
-#define FIX_2_053  ((short)16819) /* FIX(2.053119869) */
-#define FIX_2_562  ((short)20995) /* FIX(2.562915447) */
-#define FIX_3_072  ((short)25172) /* FIX(3.072711026) */
-
-enum const_index {
-  index_PW_F130_F054,
-  index_PW_F054_MF130,
-  index_PW_MF078_F117,
-  index_PW_F117_F078,
-  index_PW_MF060_MF089,
-  index_PW_MF089_F060,
-  index_PW_MF050_MF256,
-  index_PW_MF256_F050,
-  index_PD_DESCALE_P1,
-  index_PD_DESCALE_P2,
-  index_PB_CENTERJSAMP
-};
-
-static uint64_t const_value[] = {
-  _uint64_set_pi16(FIX_0_541, (FIX_0_541 + FIX_0_765),
-                   FIX_0_541, (FIX_0_541 + FIX_0_765)),
-  _uint64_set_pi16((FIX_0_541 - FIX_1_847), FIX_0_541,
-                   (FIX_0_541 - FIX_1_847), FIX_0_541),
-  _uint64_set_pi16(FIX_1_175, (FIX_1_175 - FIX_1_961),
-                   FIX_1_175, (FIX_1_175 - FIX_1_961)),
-  _uint64_set_pi16((FIX_1_175 - FIX_0_390), FIX_1_175,
-                   (FIX_1_175 - FIX_0_390), FIX_1_175),
-  _uint64_set_pi16(-FIX_0_899, (FIX_0_298 - FIX_0_899),
-                   -FIX_0_899, (FIX_0_298 - FIX_0_899)),
-  _uint64_set_pi16((FIX_1_501 - FIX_0_899), -FIX_0_899,
-                   (FIX_1_501 - FIX_0_899), -FIX_0_899),
-  _uint64_set_pi16(-FIX_2_562, (FIX_2_053 - FIX_2_562),
-                   -FIX_2_562, (FIX_2_053 - FIX_2_562)),
-  _uint64_set_pi16((FIX_3_072 - FIX_2_562), -FIX_2_562,
-                   (FIX_3_072 - FIX_2_562), -FIX_2_562),
-  _uint64_set_pi32((1 << (DESCALE_P1 - 1)), (1 << (DESCALE_P1 - 1))),
-  _uint64_set_pi32((1 << (DESCALE_P2 - 1)), (1 << (DESCALE_P2 - 1))),
-  _uint64_set_pi8(CENTERJSAMPLE, CENTERJSAMPLE, CENTERJSAMPLE, CENTERJSAMPLE,
-                  CENTERJSAMPLE, CENTERJSAMPLE, CENTERJSAMPLE, CENTERJSAMPLE)
-};
-
-#define PW_F130_F054    get_const_value(index_PW_F130_F054)
-#define PW_F054_MF130   get_const_value(index_PW_F054_MF130)
-#define PW_MF078_F117   get_const_value(index_PW_MF078_F117)
-#define PW_F117_F078    get_const_value(index_PW_F117_F078)
-#define PW_MF060_MF089  get_const_value(index_PW_MF060_MF089)
-#define PW_MF089_F060   get_const_value(index_PW_MF089_F060)
-#define PW_MF050_MF256  get_const_value(index_PW_MF050_MF256)
-#define PW_MF256_F050   get_const_value(index_PW_MF256_F050)
-#define PD_DESCALE_P1   get_const_value(index_PD_DESCALE_P1)
-#define PD_DESCALE_P2   get_const_value(index_PD_DESCALE_P2)
-#define PB_CENTERJSAMP  get_const_value(index_PB_CENTERJSAMP)
-
-
-#define test_m32_zero(mm32)  (!(*(uint32_t *)&mm32))
-#define test_m64_zero(mm64)  (!(*(uint64_t *)&mm64))
-
-
-#define DO_IDCT_COMMON(PASS) { \
-  __m64 tmp0_3l, tmp0_3h, tmp1_2l, tmp1_2h; \
-  __m64 tmp0l, tmp0h, tmp1l, tmp1h, tmp2l, tmp2h, tmp3l, tmp3h; \
-  __m64 z34l, z34h, z3l, z3h, z4l, z4h, z3, z4; \
-  __m64 out0l, out0h, out1l, out1h, out2l, out2h, out3l, out3h; \
-  __m64 out4l, out4h, out5l, out5h, out6l, out6h, out7l, out7h; \
-  \
-  z3 = _mm_add_pi16(tmp0, tmp2); \
-  z4 = _mm_add_pi16(tmp1, tmp3); \
-  \
-  /* (Original) \
-   * z5 = (z3 + z4) * 1.175875602; \
-   * z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644; \
-   * z3 += z5;  z4 += z5; \
-   * \
-   * (This implementation) \
-   * z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602; \
-   * z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644); \
-   */ \
-  \
-  z34l = _mm_unpacklo_pi16(z3, z4); \
-  z34h = _mm_unpackhi_pi16(z3, z4); \
-  z3l = _mm_madd_pi16(z34l, PW_MF078_F117); \
-  z3h = _mm_madd_pi16(z34h, PW_MF078_F117); \
-  z4l = _mm_madd_pi16(z34l, PW_F117_F078); \
-  z4h = _mm_madd_pi16(z34h, PW_F117_F078); \
-  \
-  /* (Original) \
-   * z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2; \
-   * tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869; \
-   * tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110; \
-   * z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447; \
-   * tmp0 += z1 + z3;  tmp1 += z2 + z4; \
-   * tmp2 += z2 + z3;  tmp3 += z1 + z4; \
-   * \
-   * (This implementation) \
-   * tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223; \
-   * tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447; \
-   * tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447); \
-   * tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223); \
-   * tmp0 += z3;  tmp1 += z4; \
-   * tmp2 += z3;  tmp3 += z4; \
-   */ \
-  \
-  tmp0_3l = _mm_unpacklo_pi16(tmp0, tmp3); \
-  tmp0_3h = _mm_unpackhi_pi16(tmp0, tmp3); \
-  \
-  tmp0l = _mm_madd_pi16(tmp0_3l, PW_MF060_MF089); \
-  tmp0h = _mm_madd_pi16(tmp0_3h, PW_MF060_MF089); \
-  tmp3l = _mm_madd_pi16(tmp0_3l, PW_MF089_F060); \
-  tmp3h = _mm_madd_pi16(tmp0_3h, PW_MF089_F060); \
-  \
-  tmp0l = _mm_add_pi32(tmp0l, z3l); \
-  tmp0h = _mm_add_pi32(tmp0h, z3h); \
-  tmp3l = _mm_add_pi32(tmp3l, z4l); \
-  tmp3h = _mm_add_pi32(tmp3h, z4h); \
-  \
-  tmp1_2l = _mm_unpacklo_pi16(tmp1, tmp2); \
-  tmp1_2h = _mm_unpackhi_pi16(tmp1, tmp2); \
-  \
-  tmp1l = _mm_madd_pi16(tmp1_2l, PW_MF050_MF256); \
-  tmp1h = _mm_madd_pi16(tmp1_2h, PW_MF050_MF256); \
-  tmp2l = _mm_madd_pi16(tmp1_2l, PW_MF256_F050); \
-  tmp2h = _mm_madd_pi16(tmp1_2h, PW_MF256_F050); \
-  \
-  tmp1l = _mm_add_pi32(tmp1l, z4l); \
-  tmp1h = _mm_add_pi32(tmp1h, z4h); \
-  tmp2l = _mm_add_pi32(tmp2l, z3l); \
-  tmp2h = _mm_add_pi32(tmp2h, z3h); \
-  \
-  /* Final output stage */ \
-  \
-  out0l = _mm_add_pi32(tmp10l, tmp3l); \
-  out0h = _mm_add_pi32(tmp10h, tmp3h); \
-  out7l = _mm_sub_pi32(tmp10l, tmp3l); \
-  out7h = _mm_sub_pi32(tmp10h, tmp3h); \
-  \
-  out0l = _mm_add_pi32(out0l, PD_DESCALE_P##PASS); \
-  out0h = _mm_add_pi32(out0h, PD_DESCALE_P##PASS); \
-  out0l = _mm_srai_pi32(out0l, DESCALE_P##PASS); \
-  out0h = _mm_srai_pi32(out0h, DESCALE_P##PASS); \
-  \
-  out7l = _mm_add_pi32(out7l, PD_DESCALE_P##PASS); \
-  out7h = _mm_add_pi32(out7h, PD_DESCALE_P##PASS); \
-  out7l = _mm_srai_pi32(out7l, DESCALE_P##PASS); \
-  out7h = _mm_srai_pi32(out7h, DESCALE_P##PASS); \
-  \
-  out0 = _mm_packs_pi32(out0l, out0h); \
-  out7 = _mm_packs_pi32(out7l, out7h); \
-  \
-  out1l = _mm_add_pi32(tmp11l, tmp2l); \
-  out1h = _mm_add_pi32(tmp11h, tmp2h); \
-  out6l = _mm_sub_pi32(tmp11l, tmp2l); \
-  out6h = _mm_sub_pi32(tmp11h, tmp2h); \
-  \
-  out1l = _mm_add_pi32(out1l, PD_DESCALE_P##PASS); \
-  out1h = _mm_add_pi32(out1h, PD_DESCALE_P##PASS); \
-  out1l = _mm_srai_pi32(out1l, DESCALE_P##PASS); \
-  out1h = _mm_srai_pi32(out1h, DESCALE_P##PASS); \
-  \
-  out6l = _mm_add_pi32(out6l, PD_DESCALE_P##PASS); \
-  out6h = _mm_add_pi32(out6h, PD_DESCALE_P##PASS); \
-  out6l = _mm_srai_pi32(out6l, DESCALE_P##PASS); \
-  out6h = _mm_srai_pi32(out6h, DESCALE_P##PASS); \
-  \
-  out1 = _mm_packs_pi32(out1l, out1h); \
-  out6 = _mm_packs_pi32(out6l, out6h); \
-  \
-  out2l = _mm_add_pi32(tmp12l, tmp1l); \
-  out2h = _mm_add_pi32(tmp12h, tmp1h); \
-  out5l = _mm_sub_pi32(tmp12l, tmp1l); \
-  out5h = _mm_sub_pi32(tmp12h, tmp1h); \
-  \
-  out2l = _mm_add_pi32(out2l, PD_DESCALE_P##PASS); \
-  out2h = _mm_add_pi32(out2h, PD_DESCALE_P##PASS); \
-  out2l = _mm_srai_pi32(out2l, DESCALE_P##PASS); \
-  out2h = _mm_srai_pi32(out2h, DESCALE_P##PASS); \
-  \
-  out5l = _mm_add_pi32(out5l, PD_DESCALE_P##PASS); \
-  out5h = _mm_add_pi32(out5h, PD_DESCALE_P##PASS); \
-  out5l = _mm_srai_pi32(out5l, DESCALE_P##PASS); \
-  out5h = _mm_srai_pi32(out5h, DESCALE_P##PASS); \
-  \
-  out2 = _mm_packs_pi32(out2l, out2h); \
-  out5 = _mm_packs_pi32(out5l, out5h); \
-  \
-  out3l = _mm_add_pi32(tmp13l, tmp0l); \
-  out3h = _mm_add_pi32(tmp13h, tmp0h); \
-  \
-  out4l = _mm_sub_pi32(tmp13l, tmp0l); \
-  out4h = _mm_sub_pi32(tmp13h, tmp0h); \
-  \
-  out3l = _mm_add_pi32(out3l, PD_DESCALE_P##PASS); \
-  out3h = _mm_add_pi32(out3h, PD_DESCALE_P##PASS); \
-  out3l = _mm_srai_pi32(out3l, DESCALE_P##PASS); \
-  out3h = _mm_srai_pi32(out3h, DESCALE_P##PASS); \
-  \
-  out4l = _mm_add_pi32(out4l, PD_DESCALE_P##PASS); \
-  out4h = _mm_add_pi32(out4h, PD_DESCALE_P##PASS); \
-  out4l = _mm_srai_pi32(out4l, DESCALE_P##PASS); \
-  out4h = _mm_srai_pi32(out4h, DESCALE_P##PASS); \
-  \
-  out3 = _mm_packs_pi32(out3l, out3h); \
-  out4 = _mm_packs_pi32(out4l, out4h); \
-}
-
-#define DO_IDCT_PASS1(iter) { \
-  __m64 col0l, col1l, col2l, col3l, col4l, col5l, col6l, col7l; \
-  __m64 quant0l, quant1l, quant2l, quant3l; \
-  __m64 quant4l, quant5l, quant6l, quant7l; \
-  __m64 z23, z2, z3, z23l, z23h; \
-  __m64 row01a, row01b, row01c, row01d, row23a, row23b, row23c, row23d; \
-  __m64 row0l, row0h, row1l, row1h, row2l, row2h, row3l, row3h; \
-  __m64 tmp0l, tmp0h, tmp1l, tmp1h, tmp2l, tmp2h, tmp3l, tmp3h; \
-  __m64 tmp10l, tmp10h, tmp11l, tmp11h, tmp12l, tmp12h, tmp13l, tmp13h; \
-  __m32 col0a, col1a, mm0; \
-  \
-  col0a = _mm_load_si32((__m32 *)&inptr[DCTSIZE * 1]); \
-  col1a = _mm_load_si32((__m32 *)&inptr[DCTSIZE * 2]); \
-  mm0 = _mm_or_si32(col0a, col1a); \
-  \
-  if (test_m32_zero(mm0)) { \
-    __m64 mm1, mm2; \
-    \
-    col0l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 0]); \
-    col1l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 1]); \
-    col2l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 2]); \
-    col3l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 3]); \
-    col4l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 4]); \
-    col5l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 5]); \
-    col6l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 6]); \
-    col7l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 7]); \
-    \
-    mm1 = _mm_or_si64(col1l, col3l); \
-    mm2 = _mm_or_si64(col2l, col4l); \
-    mm1 = _mm_or_si64(mm1, col5l); \
-    mm2 = _mm_or_si64(mm2, col6l); \
-    mm1 = _mm_or_si64(mm1, col7l); \
-    mm1 = _mm_or_si64(mm1, mm2); \
-    \
-    if (test_m64_zero(mm1)) { \
-      __m64 dcval, dcvall, dcvalh, row0, row1, row2, row3; \
-      \
-      /* AC terms all zero */ \
-      \
-      quant0l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 0]); \
-      \
-      dcval = _mm_mullo_pi16(col0l, quant0l); \
-      dcval = _mm_slli_pi16(dcval, PASS1_BITS);  /* dcval=(00 10 20 30) */ \
-      \
-      dcvall = _mm_unpacklo_pi16(dcval, dcval);  /* dcvall=(00 00 10 10) */ \
-      dcvalh = _mm_unpackhi_pi16(dcval, dcval);  /* dcvalh=(20 20 30 30) */ \
-      \
-      row0 = _mm_unpacklo_pi32(dcvall, dcvall);  /* row0=(00 00 00 00) */ \
-      row1 = _mm_unpackhi_pi32(dcvall, dcvall);  /* row1=(10 10 10 10) */ \
-      row2 = _mm_unpacklo_pi32(dcvalh, dcvalh);  /* row2=(20 20 20 20) */ \
-      row3 = _mm_unpackhi_pi32(dcvalh, dcvalh);  /* row3=(30 30 30 30) */ \
-      \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 0], row0); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 0 + 4], row0); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 1], row1); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 1 + 4], row1); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 2], row2); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 2 + 4], row2); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 3], row3); \
-      _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 3 + 4], row3); \
-      \
-      goto nextcolumn##iter; \
-    } \
-  } \
-  \
-  /* Even part \
-   * \
-   * (Original) \
-   * z1 = (z2 + z3) * 0.541196100; \
-   * tmp2 = z1 + z3 * -1.847759065; \
-   * tmp3 = z1 + z2 * 0.765366865; \
-   * \
-   * (This implementation) \
-   * tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065); \
-   * tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100; \
-   */ \
-  \
-  col0l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 0]);  /* (00 10 20 30) */ \
-  col2l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 2]);  /* (02 12 22 32) */ \
-  col4l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 4]);  /* (04 14 24 34) */ \
-  col6l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 6]);  /* (06 16 26 36) */ \
-  \
-  quant0l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 0]); \
-  quant2l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 2]); \
-  quant4l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 4]); \
-  quant6l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 6]); \
-  \
-  z2 = _mm_mullo_pi16(col2l, quant2l); \
-  z3 = _mm_mullo_pi16(col6l, quant6l); \
-  \
-  z23l = _mm_unpacklo_pi16(z2, z3); \
-  z23h = _mm_unpackhi_pi16(z2, z3); \
-  tmp3l = _mm_madd_pi16(z23l, PW_F130_F054); \
-  tmp3h = _mm_madd_pi16(z23h, PW_F130_F054); \
-  tmp2l = _mm_madd_pi16(z23l, PW_F054_MF130); \
-  tmp2h = _mm_madd_pi16(z23h, PW_F054_MF130); \
-  \
-  z2 = _mm_mullo_pi16(col0l, quant0l); \
-  z3 = _mm_mullo_pi16(col4l, quant4l); \
-  \
-  z23 = _mm_add_pi16(z2, z3); \
-  tmp0l = _mm_loadlo_pi16_f(z23); \
-  tmp0h = _mm_loadhi_pi16_f(z23); \
-  tmp0l = _mm_srai_pi32(tmp0l, (16 - CONST_BITS)); \
-  tmp0h = _mm_srai_pi32(tmp0h, (16 - CONST_BITS)); \
-  \
-  tmp10l = _mm_add_pi32(tmp0l, tmp3l); \
-  tmp10h = _mm_add_pi32(tmp0h, tmp3h); \
-  tmp13l = _mm_sub_pi32(tmp0l, tmp3l); \
-  tmp13h = _mm_sub_pi32(tmp0h, tmp3h); \
-  \
-  z23 = _mm_sub_pi16(z2, z3); \
-  tmp1l = _mm_loadlo_pi16_f(z23); \
-  tmp1h = _mm_loadhi_pi16_f(z23); \
-  tmp1l = _mm_srai_pi32(tmp1l, (16 - CONST_BITS)); \
-  tmp1h = _mm_srai_pi32(tmp1h, (16 - CONST_BITS)); \
-  \
-  tmp11l = _mm_add_pi32(tmp1l, tmp2l); \
-  tmp11h = _mm_add_pi32(tmp1h, tmp2h); \
-  tmp12l = _mm_sub_pi32(tmp1l, tmp2l); \
-  tmp12h = _mm_sub_pi32(tmp1h, tmp2h); \
-  \
-  /* Odd part */ \
-  \
-  col1l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 1]);  /* (01 11 21 31) */ \
-  col3l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 3]);  /* (03 13 23 33) */ \
-  col5l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 5]);  /* (05 15 25 35) */ \
-  col7l = _mm_load_si64((__m64 *)&inptr[DCTSIZE * 7]);  /* (07 17 27 37) */ \
-  \
-  quant1l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 1]); \
-  quant3l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 3]); \
-  quant5l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 5]); \
-  quant7l = _mm_load_si64((__m64 *)&quantptr[DCTSIZE * 7]); \
-  \
-  tmp0 = _mm_mullo_pi16(col7l, quant7l); \
-  tmp1 = _mm_mullo_pi16(col5l, quant5l); \
-  tmp2 = _mm_mullo_pi16(col3l, quant3l); \
-  tmp3 = _mm_mullo_pi16(col1l, quant1l); \
-  \
-  DO_IDCT_COMMON(1) \
-  \
-  /* out0=(00 10 20 30), out1=(01 11 21 31) */ \
-  /* out2=(02 12 22 32), out3=(03 13 23 33) */ \
-  /* out4=(04 14 24 34), out5=(05 15 25 35) */ \
-  /* out6=(06 16 26 36), out7=(07 17 27 37) */ \
-  \
-  /* Transpose coefficients */ \
-  \
-  row01a = _mm_unpacklo_pi16(out0, out1);     /* row01a=(00 01 10 11) */ \
-  row23a = _mm_unpackhi_pi16(out0, out1);     /* row23a=(20 21 30 31) */ \
-  row01d = _mm_unpacklo_pi16(out6, out7);     /* row01d=(06 07 16 17) */ \
-  row23d = _mm_unpackhi_pi16(out6, out7);     /* row23d=(26 27 36 37) */ \
-  \
-  row01b = _mm_unpacklo_pi16(out2, out3);     /* row01b=(02 03 12 13) */ \
-  row23b = _mm_unpackhi_pi16(out2, out3);     /* row23b=(22 23 32 33) */ \
-  row01c = _mm_unpacklo_pi16(out4, out5);     /* row01c=(04 05 14 15) */ \
-  row23c = _mm_unpackhi_pi16(out4, out5);     /* row23c=(24 25 34 35) */ \
-  \
-  row0l = _mm_unpacklo_pi32(row01a, row01b);  /* row0l=(00 01 02 03) */ \
-  row1l = _mm_unpackhi_pi32(row01a, row01b);  /* row1l=(10 11 12 13) */ \
-  row2l = _mm_unpacklo_pi32(row23a, row23b);  /* row2l=(20 21 22 23) */ \
-  row3l = _mm_unpackhi_pi32(row23a, row23b);  /* row3l=(30 31 32 33) */ \
-  \
-  row0h = _mm_unpacklo_pi32(row01c, row01d);  /* row0h=(04 05 06 07) */ \
-  row1h = _mm_unpackhi_pi32(row01c, row01d);  /* row1h=(14 15 16 17) */ \
-  row2h = _mm_unpacklo_pi32(row23c, row23d);  /* row2h=(24 25 26 27) */ \
-  row3h = _mm_unpackhi_pi32(row23c, row23d);  /* row3h=(34 35 36 37) */ \
-  \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 0], row0l); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 0 + 4], row0h); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 1], row1l); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 1 + 4], row1h); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 2], row2l); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 2 + 4], row2h); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 3], row3l); \
-  _mm_store_si64((__m64 *)&wsptr[DCTSIZE * 3 + 4], row3h); \
-}
-
-#define DO_IDCT_PASS2(ctr) { \
-  __m64 row0l, row1l, row2l, row3l, row4l, row5l, row6l, row7l; \
-  __m64 z23, z23l, z23h; \
-  __m64 col0123a, col0123b, col0123c, col0123d; \
-  __m64 col01l, col01h, col23l, col23h, row06, row17, row24, row35; \
-  __m64 col0, col1, col2, col3; \
-  __m64 tmp0l, tmp0h, tmp1l, tmp1h, tmp2l, tmp2h, tmp3l, tmp3h; \
-  __m64 tmp10l, tmp10h, tmp11l, tmp11h, tmp12l, tmp12h, tmp13l, tmp13h; \
-  \
-  row0l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 0]);  /* (00 01 02 03) */ \
-  row1l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 1]);  /* (10 11 12 13) */ \
-  row2l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 2]);  /* (20 21 22 23) */ \
-  row3l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 3]);  /* (30 31 32 33) */ \
-  row4l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 4]);  /* (40 41 42 43) */ \
-  row5l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 5]);  /* (50 51 52 53) */ \
-  row6l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 6]);  /* (60 61 62 63) */ \
-  row7l = _mm_load_si64((__m64 *)&wsptr[DCTSIZE * 7]);  /* (70 71 72 73) */ \
-  \
-  /* Even part \
-   * \
-   * (Original) \
-   * z1 = (z2 + z3) * 0.541196100; \
-   * tmp2 = z1 + z3 * -1.847759065; \
-   * tmp3 = z1 + z2 * 0.765366865; \
-   * \
-   * (This implementation) \
-   * tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065); \
-   * tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100; \
-   */ \
-  \
-  z23l = _mm_unpacklo_pi16(row2l, row6l); \
-  z23h = _mm_unpackhi_pi16(row2l, row6l); \
-  \
-  tmp3l = _mm_madd_pi16(z23l, PW_F130_F054); \
-  tmp3h = _mm_madd_pi16(z23h, PW_F130_F054); \
-  tmp2l = _mm_madd_pi16(z23l, PW_F054_MF130); \
-  tmp2h = _mm_madd_pi16(z23h, PW_F054_MF130); \
-  \
-  z23 = _mm_add_pi16(row0l, row4l); \
-  tmp0l = _mm_loadlo_pi16_f(z23); \
-  tmp0h = _mm_loadhi_pi16_f(z23); \
-  tmp0l = _mm_srai_pi32(tmp0l, (16 - CONST_BITS)); \
-  tmp0h = _mm_srai_pi32(tmp0h, (16 - CONST_BITS)); \
-  \
-  tmp10l = _mm_add_pi32(tmp0l, tmp3l); \
-  tmp10h = _mm_add_pi32(tmp0h, tmp3h); \
-  tmp13l = _mm_sub_pi32(tmp0l, tmp3l); \
-  tmp13h = _mm_sub_pi32(tmp0h, tmp3h); \
-  \
-  z23 = _mm_sub_pi16(row0l, row4l); \
-  tmp1l = _mm_loadlo_pi16_f(z23); \
-  tmp1h = _mm_loadhi_pi16_f(z23); \
-  tmp1l = _mm_srai_pi32(tmp1l, (16 - CONST_BITS)); \
-  tmp1h = _mm_srai_pi32(tmp1h, (16 - CONST_BITS)); \
-  \
-  tmp11l = _mm_add_pi32(tmp1l, tmp2l); \
-  tmp11h = _mm_add_pi32(tmp1h, tmp2h); \
-  tmp12l = _mm_sub_pi32(tmp1l, tmp2l); \
-  tmp12h = _mm_sub_pi32(tmp1h, tmp2h); \
-  \
-  /* Odd part */ \
-  \
-  tmp0 = row7l; \
-  tmp1 = row5l; \
-  tmp2 = row3l; \
-  tmp3 = row1l; \
-  \
-  DO_IDCT_COMMON(2) \
-  \
-  /* out0=(00 01 02 03), out1=(10 11 12 13) */ \
-  /* out2=(20 21 22 23), out3=(30 31 32 33) */ \
-  /* out4=(40 41 42 43), out5=(50 51 52 53) */ \
-  /* out6=(60 61 62 63), out7=(70 71 72 73) */ \
-  \
-  row06 = _mm_packs_pi16(out0, out6);  /* row06=(00 01 02 03 60 61 62 63) */ \
-  row17 = _mm_packs_pi16(out1, out7);  /* row17=(10 11 12 13 70 71 72 73) */ \
-  row24 = _mm_packs_pi16(out2, out4);  /* row24=(20 21 22 23 40 41 42 43) */ \
-  row35 = _mm_packs_pi16(out3, out5);  /* row35=(30 31 32 33 50 51 52 53) */ \
-  \
-  row06 = _mm_add_pi8(row06, PB_CENTERJSAMP); \
-  row17 = _mm_add_pi8(row17, PB_CENTERJSAMP); \
-  row24 = _mm_add_pi8(row24, PB_CENTERJSAMP); \
-  row35 = _mm_add_pi8(row35, PB_CENTERJSAMP); \
-  \
-  /* Transpose coefficients */ \
-  \
-  col0123a = _mm_unpacklo_pi8(row06, row17);  /* col0123a=(00 10 01 11 02 12 03 13) */ \
-  col0123d = _mm_unpackhi_pi8(row06, row17);  /* col0123d=(60 70 61 71 62 72 63 73) */ \
-  col0123b = _mm_unpacklo_pi8(row24, row35);  /* col0123b=(20 30 21 31 22 32 23 33) */ \
-  col0123c = _mm_unpackhi_pi8(row24, row35);  /* col0123c=(40 50 41 51 42 52 43 53) */ \
-  \
-  col01l = _mm_unpacklo_pi16(col0123a, col0123b);  /* col01l=(00 10 20 30 01 11 21 31) */ \
-  col23l = _mm_unpackhi_pi16(col0123a, col0123b);  /* col23l=(02 12 22 32 03 13 23 33) */ \
-  col01h = _mm_unpacklo_pi16(col0123c, col0123d);  /* col01h=(40 50 60 70 41 51 61 71) */ \
-  col23h = _mm_unpackhi_pi16(col0123c, col0123d);  /* col23h=(42 52 62 72 43 53 63 73) */ \
-  \
-  col0 = _mm_unpacklo_pi32(col01l, col01h);   /* col0=(00 10 20 30 40 50 60 70) */ \
-  col1 = _mm_unpackhi_pi32(col01l, col01h);   /* col1=(01 11 21 31 41 51 61 71) */ \
-  col2 = _mm_unpacklo_pi32(col23l, col23h);   /* col2=(02 12 22 32 42 52 62 72) */ \
-  col3 = _mm_unpackhi_pi32(col23l, col23h);   /* col3=(03 13 23 33 43 53 63 73) */ \
-  \
-  _mm_store_si64((__m64 *)(output_buf[ctr + 0] + output_col), col0); \
-  _mm_store_si64((__m64 *)(output_buf[ctr + 1] + output_col), col1); \
-  _mm_store_si64((__m64 *)(output_buf[ctr + 2] + output_col), col2); \
-  _mm_store_si64((__m64 *)(output_buf[ctr + 3] + output_col), col3); \
-}
-
-void jsimd_idct_islow_mmi(void *dct_table, JCOEFPTR coef_block,
-                          JSAMPARRAY output_buf, JDIMENSION output_col)
-{
-  __m64 tmp0, tmp1, tmp2, tmp3;
-  __m64 out0, out1, out2, out3, out4, out5, out6, out7;
-  JCOEFPTR inptr;
-  ISLOW_MULT_TYPE *quantptr;
-  JCOEF *wsptr;
-  JCOEF workspace[DCTSIZE2];  /* buffers data between passes */
-
-  /* Pass 1: process columns. */
-
-  inptr = coef_block;
-  quantptr = (ISLOW_MULT_TYPE *)dct_table;
-  wsptr = workspace;
-
-  DO_IDCT_PASS1(1)
-nextcolumn1:
-  inptr += 4;
-  quantptr += 4;
-  wsptr += DCTSIZE * 4;
-  DO_IDCT_PASS1(2)
-nextcolumn2:
-
-  /* Pass 2: process rows. */
-
-  wsptr = workspace;
-
-  DO_IDCT_PASS2(0)
-  wsptr += 4;
-  DO_IDCT_PASS2(4)
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jquanti-mmi.c b/src/third_party/libjpeg-turbo/simd/loongson/jquanti-mmi.c
deleted file mode 100644
index f9a3f81..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jquanti-mmi.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- * Copyright (C) 2018, D. R. Commander.  All Rights Reserved.
- *
- * Based on the x86 SIMD extension for IJG JPEG library
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* INTEGER QUANTIZATION AND SAMPLE CONVERSION */
-
-#include "jsimd_mmi.h"
-
-
-#define DO_QUANT() { \
-  mm2 = _mm_load_si64((__m64 *)&workspace[0]); \
-  mm3 = _mm_load_si64((__m64 *)&workspace[4]); \
-  \
-  mm0 = mm2; \
-  mm1 = mm3; \
-  \
-  mm2 = _mm_srai_pi16(mm2, (WORD_BIT - 1));   /* -1 if value < 0, */ \
-                                              /* 0 otherwise */ \
-  mm3 = _mm_srai_pi16(mm3, (WORD_BIT - 1)); \
-  \
-  mm0 = _mm_xor_si64(mm0, mm2);               /* val = -val */ \
-  mm1 = _mm_xor_si64(mm1, mm3); \
-  mm0 = _mm_sub_pi16(mm0, mm2); \
-  mm1 = _mm_sub_pi16(mm1, mm3); \
-  \
-  corr0 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 1]);  /* correction */ \
-  corr1 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 1 + 4]); \
-  \
-  mm0 = _mm_add_pi16(mm0, corr0);             /* correction + roundfactor */ \
-  mm1 = _mm_add_pi16(mm1, corr1); \
-  \
-  mm4 = mm0; \
-  mm5 = mm1; \
-  \
-  recip0 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 0]);  /* reciprocal */ \
-  recip1 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 0 + 4]); \
-  \
-  mm0 = _mm_mulhi_pi16(mm0, recip0); \
-  mm1 = _mm_mulhi_pi16(mm1, recip1); \
-  \
-  mm0 = _mm_add_pi16(mm0, mm4);  /* reciprocal is always negative */ \
-  mm1 = _mm_add_pi16(mm1, mm5);  /* (MSB=1), so we always need to add the */ \
-                                 /* initial value (input value is never */ \
-                                 /* negative as we inverted it at the */ \
-                                 /* start of this routine) */ \
-  \
-  scale0 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 2]);  /* scale */ \
-  scale1 = _mm_load_si64((__m64 *)&divisors[DCTSIZE2 * 2 + 4]); \
-  \
-  mm6 = scale0; \
-  mm7 = scale1; \
-  mm4 = mm0; \
-  mm5 = mm1; \
-  \
-  mm0 = _mm_mulhi_pi16(mm0, mm6); \
-  mm1 = _mm_mulhi_pi16(mm1, mm7); \
-  \
-  mm6 = _mm_srai_pi16(mm6, (WORD_BIT - 1));   /* determine if scale... */ \
-                                              /* is negative */ \
-  mm7 = _mm_srai_pi16(mm7, (WORD_BIT - 1)); \
-  \
-  mm6 = _mm_and_si64(mm6, mm4);               /* and add input if it is */ \
-  mm7 = _mm_and_si64(mm7, mm5); \
-  mm0 = _mm_add_pi16(mm0, mm6); \
-  mm1 = _mm_add_pi16(mm1, mm7); \
-  \
-  mm4 = _mm_srai_pi16(mm4, (WORD_BIT - 1));   /* then check if... */ \
-  mm5 = _mm_srai_pi16(mm5, (WORD_BIT - 1));   /* negative input */ \
-  \
-  mm4 = _mm_and_si64(mm4, scale0);            /* and add scale if it is */ \
-  mm5 = _mm_and_si64(mm5, scale1); \
-  mm0 = _mm_add_pi16(mm0, mm4); \
-  mm1 = _mm_add_pi16(mm1, mm5); \
-  \
-  mm0 = _mm_xor_si64(mm0, mm2);               /* val = -val */ \
-  mm1 = _mm_xor_si64(mm1, mm3); \
-  mm0 = _mm_sub_pi16(mm0, mm2); \
-  mm1 = _mm_sub_pi16(mm1, mm3); \
-  \
-  _mm_store_si64((__m64 *)&output_ptr[0], mm0); \
-  _mm_store_si64((__m64 *)&output_ptr[4], mm1); \
-  \
-  workspace += DCTSIZE; \
-  divisors += DCTSIZE; \
-  output_ptr += DCTSIZE; \
-}
-
-
-void jsimd_quantize_mmi(JCOEFPTR coef_block, DCTELEM *divisors,
-                        DCTELEM *workspace)
-{
-  JCOEFPTR output_ptr = coef_block;
-  __m64 mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
-  __m64 corr0, corr1, recip0, recip1, scale0, scale1;
-
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-  DO_QUANT()
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jsimd.c b/src/third_party/libjpeg-turbo/simd/loongson/jsimd.c
deleted file mode 100644
index e8b1832..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jsimd.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * jsimd_loongson.c
- *
- * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2009-2011, 2014, 2016, 2018, D. R. Commander.
- * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
- * Copyright (C) 2015, 2018, Matthieu Darbois.
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *
- * Based on the x86 SIMD extension for IJG JPEG library,
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- * For conditions of distribution and use, see copyright notice in jsimdext.inc
- *
- * This file contains the interface between the "normal" portions
- * of the library and the SIMD implementations when running on a
- * Loongson architecture.
- */
-
-#define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
-#include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
-
-static unsigned int simd_support = ~0;
-
-/*
- * Check what SIMD accelerations are supported.
- *
- * FIXME: This code is racy under a multi-threaded environment.
- */
-LOCAL(void)
-init_simd(void)
-{
-#ifndef NO_GETENV
-  char *env = NULL;
-#endif
-
-  if (simd_support != ~0U)
-    return;
-
-  simd_support |= JSIMD_MMI;
-
-#ifndef NO_GETENV
-  /* Force different settings through environment variables */
-  env = getenv("JSIMD_FORCENONE");
-  if ((env != NULL) && (strcmp(env, "1") == 0))
-    simd_support = 0;
-#endif
-}
-
-GLOBAL(int)
-jsimd_can_rgb_ycc(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_rgb_gray(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb565(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_c_can_null_convert(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                      JSAMPIMAGE output_buf, JDIMENSION output_row,
-                      int num_rows)
-{
-  void (*mmifct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
-
-  switch (cinfo->in_color_space) {
-  case JCS_EXT_RGB:
-    mmifct = jsimd_extrgb_ycc_convert_mmi;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    mmifct = jsimd_extrgbx_ycc_convert_mmi;
-    break;
-  case JCS_EXT_BGR:
-    mmifct = jsimd_extbgr_ycc_convert_mmi;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    mmifct = jsimd_extbgrx_ycc_convert_mmi;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    mmifct = jsimd_extxbgr_ycc_convert_mmi;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    mmifct = jsimd_extxrgb_ycc_convert_mmi;
-    break;
-  default:
-    mmifct = jsimd_rgb_ycc_convert_mmi;
-    break;
-  }
-
-  mmifct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
-}
-
-GLOBAL(void)
-jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                       JSAMPIMAGE output_buf, JDIMENSION output_row,
-                       int num_rows)
-{
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                      JDIMENSION input_row, JSAMPARRAY output_buf,
-                      int num_rows)
-{
-  void (*mmifct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    mmifct = jsimd_ycc_extrgb_convert_mmi;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    mmifct = jsimd_ycc_extrgbx_convert_mmi;
-    break;
-  case JCS_EXT_BGR:
-    mmifct = jsimd_ycc_extbgr_convert_mmi;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    mmifct = jsimd_ycc_extbgrx_convert_mmi;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    mmifct = jsimd_ycc_extxbgr_convert_mmi;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    mmifct = jsimd_ycc_extxrgb_convert_mmi;
-    break;
-  default:
-    mmifct = jsimd_ycc_rgb_convert_mmi;
-    break;
-  }
-
-  mmifct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                         JDIMENSION input_row, JSAMPARRAY output_buf,
-                         int num_rows)
-{
-}
-
-GLOBAL(void)
-jsimd_c_null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                     JSAMPIMAGE output_buf, JDIMENSION output_row,
-                     int num_rows)
-{
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_smooth_downsample(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_downsample(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v2_downsample_mmi(cinfo->image_width, cinfo->max_v_samp_factor,
-                            compptr->v_samp_factor, compptr->width_in_blocks,
-                            input_data, output_data);
-}
-
-GLOBAL(void)
-jsimd_h2v2_smooth_downsample(j_compress_ptr cinfo,
-                             jpeg_component_info *compptr,
-                             JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-}
-
-GLOBAL(void)
-jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_int_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-}
-
-GLOBAL(void)
-jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-}
-
-GLOBAL(void)
-jsimd_int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                   JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_fancy_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_fancy_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v2_fancy_upsample_mmi(cinfo->max_v_samp_factor,
-                                compptr->downsampled_width, input_data,
-                                output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_merged_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_merged_upsample(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-}
-
-GLOBAL(void)
-jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-}
-
-GLOBAL(int)
-jsimd_can_convsamp(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_convsamp_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
-               DCTELEM *workspace)
-{
-}
-
-GLOBAL(void)
-jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
-                     FAST_FLOAT *workspace)
-{
-}
-
-GLOBAL(int)
-jsimd_can_fdct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_ifast(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_fdct_islow(DCTELEM *data)
-{
-  jsimd_fdct_islow_mmi(data);
-}
-
-GLOBAL(void)
-jsimd_fdct_ifast(DCTELEM *data)
-{
-}
-
-GLOBAL(void)
-jsimd_fdct_float(FAST_FLOAT *data)
-{
-}
-
-GLOBAL(int)
-jsimd_can_quantize(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_quantize_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
-{
-  jsimd_quantize_mmi(coef_block, divisors, workspace);
-}
-
-GLOBAL(void)
-jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
-                     FAST_FLOAT *workspace)
-{
-}
-
-GLOBAL(int)
-jsimd_can_idct_2x2(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_4x4(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_6x6(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_12x12(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-}
-
-GLOBAL(void)
-jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-}
-
-GLOBAL(void)
-jsimd_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-}
-
-GLOBAL(void)
-jsimd_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-}
-
-GLOBAL(int)
-jsimd_can_idct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_MMI)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_ifast(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  jsimd_idct_islow_mmi(compptr->dct_table, coef_block, output_buf, output_col);
-}
-
-GLOBAL(void)
-jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-}
-
-GLOBAL(void)
-jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-}
-
-GLOBAL(int)
-jsimd_can_huff_encode_one_block(void)
-{
-  return 0;
-}
-
-GLOBAL(JOCTET *)
-jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
-                            int last_dc_val, c_derived_tbl *dctbl,
-                            c_derived_tbl *actbl)
-{
-  return NULL;
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_first_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
-                                  const int *jpeg_natural_order_start, int Sl,
-                                  int Al, JCOEF *values, size_t *zerobits)
-{
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_refine_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
-                                   const int *jpeg_natural_order_start, int Sl,
-                                   int Al, JCOEF *absvalues, size_t *bits)
-{
-  return 0;
-}
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/jsimd_mmi.h b/src/third_party/libjpeg-turbo/simd/loongson/jsimd_mmi.h
deleted file mode 100644
index 2506aa8..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/jsimd_mmi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- * Authors:  ZhuChen     <zhuchen@loongson.cn>
- *           CaiWanwei   <caiwanwei@loongson.cn>
- *           SunZhangzhi <sunzhangzhi-cq@loongson.cn>
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
-#include "../../jdct.h"
-#include "loongson-mmintrin.h"
-
-
-/* Common code */
-
-#define SIZEOF_MMWORD  8
-#define BYTE_BIT  8
-#define WORD_BIT  16
-#define SCALEBITS  16
-
-#define _uint64_set_pi8(a, b, c, d, e, f, g, h) \
-  (((uint64_t)(uint8_t)a << 56) | \
-   ((uint64_t)(uint8_t)b << 48) | \
-   ((uint64_t)(uint8_t)c << 40) | \
-   ((uint64_t)(uint8_t)d << 32) | \
-   ((uint64_t)(uint8_t)e << 24) | \
-   ((uint64_t)(uint8_t)f << 16) | \
-   ((uint64_t)(uint8_t)g << 8)  | \
-   ((uint64_t)(uint8_t)h))
-#define _uint64_set_pi16(a, b, c, d)  (((uint64_t)(uint16_t)a << 48) | \
-                                       ((uint64_t)(uint16_t)b << 32) | \
-                                       ((uint64_t)(uint16_t)c << 16) | \
-                                       ((uint64_t)(uint16_t)d))
-#define _uint64_set_pi32(a, b)  (((uint64_t)(uint32_t)a << 32) | \
-                                 ((uint64_t)(uint32_t)b))
-
-#define get_const_value(index)  (*(__m64 *)&const_value[index])
diff --git a/src/third_party/libjpeg-turbo/simd/loongson/loongson-mmintrin.h b/src/third_party/libjpeg-turbo/simd/loongson/loongson-mmintrin.h
deleted file mode 100644
index 4aea763..0000000
--- a/src/third_party/libjpeg-turbo/simd/loongson/loongson-mmintrin.h
+++ /dev/null
@@ -1,1307 +0,0 @@
-/*
- * Loongson MMI optimizations for libjpeg-turbo
- *
- * Copyright (C) 2016-2017, Loongson Technology Corporation Limited, BeiJing.
- *                          All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#ifndef __LOONGSON_MMINTRIN_H__
-#define __LOONGSON_MMINTRIN_H__
-
-#include <stdint.h>
-
-
-#define FUNCTION_ATTRIBS \
-  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-
-
-/* Vectors are stored in 64-bit floating-point registers. */
-typedef double __m64;
-
-/* Having a 32-bit datatype allows us to use 32-bit loads in places like
-   load8888. */
-typedef float __m32;
-
-
-/********** Set Operations **********/
-
-extern __inline __m64
-_mm_setzero_si64(void)
-{
-  return 0.0;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set_pi8(uint8_t __b7, uint8_t __b6, uint8_t __b5, uint8_t __b4,
-            uint8_t __b3, uint8_t __b2, uint8_t __b1, uint8_t __b0)
-{
-  __m64 ret;
-  uint32_t lo = ((uint32_t)__b6 << 24) |
-                ((uint32_t)__b4 << 16) |
-                ((uint32_t)__b2 << 8) |
-                (uint32_t)__b0;
-  uint32_t hi = ((uint32_t)__b7 << 24) |
-                ((uint32_t)__b5 << 16) |
-                ((uint32_t)__b3 << 8) |
-                (uint32_t)__b1;
-
-  asm("mtc1      %1, %0\n\t"
-      "mtc1      %2, $f0\n\t"
-      "punpcklbh %0, %0, $f0\n\t"
-      : "=f" (ret)
-      : "r" (lo), "r" (hi)
-      : "$f0"
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set_pi16(uint16_t __h3, uint16_t __h2, uint16_t __h1, uint16_t __h0)
-{
-  __m64 ret;
-  uint32_t lo = ((uint32_t)__h2 << 16) | (uint32_t)__h0;
-  uint32_t hi = ((uint32_t)__h3 << 16) | (uint32_t)__h1;
-
-  asm("mtc1      %1, %0\n\t"
-      "mtc1      %2, $f0\n\t"
-      "punpcklhw %0, %0, $f0\n\t"
-      : "=f" (ret)
-      : "r" (lo), "r" (hi)
-      : "$f0"
-     );
-
-  return ret;
-}
-
-#define _MM_SHUFFLE(fp3, fp2, fp1, fp0) \
-  (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0))
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set_pi32(uint32_t __i1, uint32_t __i0)
-{
-  if (__builtin_constant_p(__i1) && __builtin_constant_p(__i0)) {
-    uint64_t val = ((uint64_t)__i1 << 32) |
-                   ((uint64_t)__i0 <<  0);
-
-    return *(__m64 *)&val;
-  } else if (__i1 == __i0) {
-    uint64_t imm = _MM_SHUFFLE(1, 0, 1, 0);
-    __m64 ret;
-
-    asm("pshufh %0, %1, %2\n\t"
-        : "=f" (ret)
-        : "f" (*(__m32 *)&__i1), "f" (*(__m64 *)&imm)
-       );
-
-    return ret;
-  } else {
-    uint64_t val = ((uint64_t)__i1 << 32) |
-                   ((uint64_t)__i0 <<  0);
-
-    return *(__m64 *)&val;
-  }
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set1_pi8(uint8_t __b0)
-{
-  __m64 ret;
-
-  asm("sll    $8, %1, 8\n\t"
-      "or     %1, %1, $8\n\t"
-      "mtc1   %1, %0\n\t"
-      "mtc1   $0, $f0\n\t"
-      "pshufh %0, %0, $f0\n\t"
-      : "=f" (ret)
-      : "r" (__b0)
-      : "$8", "$f0"
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set1_pi16(uint16_t __h0)
-{
-  __m64 ret;
-
-  asm("mtc1   %1, %0\n\t"
-      "mtc1   $0, $f0\n\t"
-      "pshufh %0, %0, $f0\n\t"
-      : "=f" (ret)
-      : "r" (__h0)
-      : "$8", "$f0"
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_set1_pi32(unsigned __i0)
-{
-  return _mm_set_pi32(__i0, __i0);
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_setr_pi8(uint8_t __h0, uint8_t __h1, uint8_t __h2, uint8_t __h3,
-             uint8_t __h4, uint8_t __h5, uint8_t __h6, uint8_t __h7)
-{
-  return _mm_set_pi8(__h7, __h6, __h5, __h4,
-                     __h3, __h2, __h1, __h0);
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_setr_pi16(uint16_t __w0, uint16_t __w1, uint16_t __w2, uint16_t __w3)
-{
-  return _mm_set_pi16(__w3, __w2, __w1, __w0);
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_setr_pi32(uint32_t __i0, uint32_t __i1)
-{
-  return _mm_set_pi32(__i1, __i0);
-}
-
-
-/********** Arithmetic Operations **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_add_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_add_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_add_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_add_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_adds_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddsb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_adds_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddsh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_adds_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddusb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_adds_pu16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("paddush %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_avg_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pavgb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_avg_pu16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pavgh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_madd_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmaddhw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_max_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmaxsh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_max_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmaxub %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_min_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pminsh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_min_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pminub %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline int FUNCTION_ATTRIBS
-_mm_movemask_pi8(__m64 __m1)
-{
-  int ret;
-
-  asm("pmovmskb %0, %1\n\t"
-      : "=r" (ret)
-      : "y" (__m1)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_mulhi_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmulhh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_mulhi_pu16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmulhuh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_mullo_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmullh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_mul_pu32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pmuluw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_sad_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psadbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_asub_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pasubub %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_biadd_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("biadd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_sub_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_sub_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_sub_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_sub_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_subs_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubsb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_subs_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubsh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_subs_pu8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubusb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_subs_pu16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("psubush %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-/********** Logical Operations **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_and_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("and %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_andnot_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("andn %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_or_si32(__m32 __m1, __m32 __m2)
-{
-  __m32 ret;
-
-  asm("or %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_or_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("or %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_xor_si64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("xor %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-/********** Shift Operations **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_slli_pi16(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psllh  %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_slli_pi32(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psllw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_slli_si64(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("dsll  %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srli_pi16(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psrlh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srli_pi32(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psrlw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srli_si64(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("dsrl  %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srai_pi16(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psrah %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srai_pi32(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("psraw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_srai_si64(__m64 __m, int64_t __count)
-{
-  __m64 ret;
-
-  asm("dsra %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__count)
-     );
-
-  return ret;
-}
-
-
-/********** Conversion Intrinsics **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-to_m64(uint64_t x)
-{
-  return *(__m64 *)&x;
-}
-
-extern __inline uint64_t FUNCTION_ATTRIBS
-to_uint64(__m64 x)
-{
-  return *(uint64_t *)&x;
-}
-
-
-/********** Comparison Intrinsics **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpeqb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpeqh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpeqw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpgtb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpgth %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmpgt_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpgtw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmplt_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpltb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmplt_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmplth %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_cmplt_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("pcmpltw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-/********** Miscellaneous Operations **********/
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_packs_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("packsshb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_packs_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("packsswh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_packs_pi32_f(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("packsswh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_packs_pu16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("packushb %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_extract_pi16(__m64 __m, int64_t __pos)
-{
-  __m64 ret;
-
-  asm("pextrh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__pos)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_insert_pi16(__m64 __m1, __m64 __m2, int64_t __pos)
-{
-  __m64 ret;
-
-  switch (__pos) {
-  case 0:
-
-    asm("pinsrh_0 %0, %1, %2\n\t"
-        : "=f" (ret)
-        : "f" (__m1), "f" (__m2), "i" (__pos)
-       );
-
-    break;
-
-  case 1:
-
-    asm("pinsrh_1 %0, %1, %2\n\t"
-        : "=f" (ret)
-        : "f" (__m1), "f" (__m2), "i" (__pos)
-       );
-
-    break;
-  case 2:
-
-    asm("pinsrh_2 %0, %1, %2\n\t"
-        : "=f" (ret)
-        : "f" (__m1), "f" (__m2), "i" (__pos)
-       );
-
-    break;
-
-  case 3:
-
-    asm("pinsrh_3 %0, %1, %2\n\t"
-        : "=f" (ret)
-        : "f" (__m1), "f" (__m2), "i" (__pos)
-       );
-
-    break;
-  }
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_shuffle_pi16(__m64 __m, int64_t __n)
-{
-  __m64 ret;
-
-  asm("pshufh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m), "f" (*(__m64 *)&__n)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpackhi_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpckhbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpackhi_pi8_f(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpckhbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpackhi_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpckhhw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpackhi_pi16_f(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpckhhw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpackhi_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpckhwd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi8(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-/* Since punpcklbh cares about the high 32-bits, we use the __m64 datatype,
-   which preserves the data. */
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi8_f64(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-/* Since punpcklbh doesn't care about the high 32-bits, we use the __m32,
-   datatype, which allows load8888 to use 32-bit loads. */
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi8_f(__m32 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklbh %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi16(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklhw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi16_f(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklhw %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi32(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklwd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_unpacklo_pi32_f(__m64 __m1, __m64 __m2)
-{
-  __m64 ret;
-
-  asm("punpcklwd %0, %1, %2\n\t"
-      : "=f" (ret)
-      : "f" (__m1), "f" (__m2)
-     );
-
-  return ret;
-}
-
-extern __inline void FUNCTION_ATTRIBS
-_mm_store_pi32(__m32 *dest, __m64 src)
-{
-  src = _mm_packs_pu16(src, _mm_setzero_si64());
-
-  asm("swc1 %1, %0\n\t"
-      : "=m" (*dest)
-      : "f" (src)
-      : "memory"
-     );
-}
-
-extern __inline void FUNCTION_ATTRIBS
-_mm_store_si64(__m64 *dest, __m64 src)
-{
-  asm("gssdlc1 %1, 7+%0\n\t"
-      "gssdrc1 %1, %0\n\t"
-      : "=m" (*dest)
-      : "f" (src)
-      : "memory"
-     );
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_load_si32(const __m32 *src)
-{
-  __m32 ret;
-
-  asm("lwc1 %0, %1\n\t"
-      : "=f" (ret)
-      : "m" (*src)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_load_si64(const __m64 *src)
-{
-  __m64 ret;
-
-  asm("ldc1 %0, %1\n\t"
-      : "=f" (ret)
-      : "m" (*src)
-     );
-
-  return ret;
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadlo_pi8(const uint32_t *src)
-{
-  return _mm_unpacklo_pi8_f(*(__m32 *)src, _mm_setzero_si64());
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadlo_pi8_f(__m64 src)
-{
-  return _mm_unpacklo_pi8_f64(src, _mm_setzero_si64());
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadhi_pi8_f(__m64 src)
-{
-  return _mm_unpackhi_pi8_f(src, _mm_setzero_si64());
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadlo_pi16(__m64 src)
-{
-  return _mm_unpacklo_pi16(src, _mm_setzero_si64());
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadlo_pi16_f(__m64 src)
-{
-  return _mm_unpacklo_pi16_f(_mm_setzero_si64(), src);
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadhi_pi16(__m64 src)
-{
-  return _mm_unpackhi_pi16(src, _mm_setzero_si64());
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_loadhi_pi16_f(__m64 src)
-{
-  return _mm_unpackhi_pi16_f(_mm_setzero_si64(), src);
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_expand_alpha(__m64 pixel)
-{
-  return _mm_shuffle_pi16(pixel, _MM_SHUFFLE(3, 3, 3, 3));
-}
-
-extern __inline __m64 FUNCTION_ATTRIBS
-_mm_expand_alpha_rev(__m64 pixel)
-{
-  return _mm_shuffle_pi16(pixel, _MM_SHUFFLE(0, 0, 0, 0));
-}
-
-#endif  /* __LOONGSON_MMINTRIN_H__ */
diff --git a/src/third_party/libjpeg-turbo/simd/mips/jsimd.c b/src/third_party/libjpeg-turbo/simd/mips/jsimd.c
deleted file mode 100644
index af886f6..0000000
--- a/src/third_party/libjpeg-turbo/simd/mips/jsimd.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * jsimd_mips.c
- *
- * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2009-2011, 2014, 2016, 2018, D. R. Commander.
- * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
- * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
- *
- * Based on the x86 SIMD extension for IJG JPEG library,
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- * For conditions of distribution and use, see copyright notice in jsimdext.inc
- *
- * This file contains the interface between the "normal" portions
- * of the library and the SIMD implementations when running on a
- * MIPS architecture.
- */
-
-#define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
-#include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-static unsigned int simd_support = ~0;
-
-#if defined(__linux__)
-
-LOCAL(int)
-parse_proc_cpuinfo(const char *search_string)
-{
-  const char *file_name = "/proc/cpuinfo";
-  char cpuinfo_line[256];
-  FILE *f = NULL;
-
-  simd_support = 0;
-
-  if ((f = fopen(file_name, "r")) != NULL) {
-    while (fgets(cpuinfo_line, sizeof(cpuinfo_line), f) != NULL) {
-      if (strstr(cpuinfo_line, search_string) != NULL) {
-        fclose(f);
-        simd_support |= JSIMD_DSPR2;
-        return 1;
-      }
-    }
-    fclose(f);
-  }
-  /* Did not find string in the proc file, or not Linux ELF. */
-  return 0;
-}
-
-#endif
-
-/*
- * Check what SIMD accelerations are supported.
- *
- * FIXME: This code is racy under a multi-threaded environment.
- */
-LOCAL(void)
-init_simd(void)
-{
-#ifndef NO_GETENV
-  char *env = NULL;
-#endif
-
-  if (simd_support != ~0U)
-    return;
-
-  simd_support = 0;
-
-#if defined(__MIPSEL__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2)
-  simd_support |= JSIMD_DSPR2;
-#elif defined(__linux__)
-  /* We still have a chance to use MIPS DSPR2 regardless of globally used
-   * -mdspr2 options passed to gcc by performing runtime detection via
-   * /proc/cpuinfo parsing on linux */
-  if (!parse_proc_cpuinfo("MIPS 74K"))
-    return;
-#endif
-
-#ifndef NO_GETENV
-  /* Force different settings through environment variables */
-  env = getenv("JSIMD_FORCEDSPR2");
-  if ((env != NULL) && (strcmp(env, "1") == 0))
-    simd_support = JSIMD_DSPR2;
-  env = getenv("JSIMD_FORCENONE");
-  if ((env != NULL) && (strcmp(env, "1") == 0))
-    simd_support = 0;
-#endif
-}
-
-static const int mips_idct_ifast_coefs[4] = {
-  0x45404540,           /* FIX( 1.082392200 / 2) =  17734 = 0x4546 */
-  0x5A805A80,           /* FIX( 1.414213562 / 2) =  23170 = 0x5A82 */
-  0x76407640,           /* FIX( 1.847759065 / 2) =  30274 = 0x7642 */
-  0xAC60AC60            /* FIX(-2.613125930 / 4) = -21407 = 0xAC61 */
-};
-
-/* The following struct is borrowed from jdsample.c */
-typedef void (*upsample1_ptr) (j_decompress_ptr cinfo,
-                               jpeg_component_info *compptr,
-                               JSAMPARRAY input_data,
-                               JSAMPARRAY *output_data_ptr);
-typedef struct {
-  struct jpeg_upsampler pub;
-  JSAMPARRAY color_buf[MAX_COMPONENTS];
-  upsample1_ptr methods[MAX_COMPONENTS];
-  int next_row_out;
-  JDIMENSION rows_to_go;
-  int rowgroup_height[MAX_COMPONENTS];
-  UINT8 h_expand[MAX_COMPONENTS];
-  UINT8 v_expand[MAX_COMPONENTS];
-} my_upsampler;
-
-typedef my_upsampler *my_upsample_ptr;
-
-GLOBAL(int)
-jsimd_can_rgb_ycc(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_rgb_gray(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb565(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_c_can_null_convert(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                      JSAMPIMAGE output_buf, JDIMENSION output_row,
-                      int num_rows)
-{
-  void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
-
-  switch (cinfo->in_color_space) {
-  case JCS_EXT_RGB:
-    dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    dspr2fct = jsimd_extrgbx_ycc_convert_dspr2;
-    break;
-  case JCS_EXT_BGR:
-    dspr2fct = jsimd_extbgr_ycc_convert_dspr2;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    dspr2fct = jsimd_extbgrx_ycc_convert_dspr2;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    dspr2fct = jsimd_extxbgr_ycc_convert_dspr2;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    dspr2fct = jsimd_extxrgb_ycc_convert_dspr2;
-    break;
-  default:
-    dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
-    break;
-  }
-
-  dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
-}
-
-GLOBAL(void)
-jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                       JSAMPIMAGE output_buf, JDIMENSION output_row,
-                       int num_rows)
-{
-  void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
-
-  switch (cinfo->in_color_space) {
-  case JCS_EXT_RGB:
-    dspr2fct = jsimd_extrgb_gray_convert_dspr2;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    dspr2fct = jsimd_extrgbx_gray_convert_dspr2;
-    break;
-  case JCS_EXT_BGR:
-    dspr2fct = jsimd_extbgr_gray_convert_dspr2;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    dspr2fct = jsimd_extbgrx_gray_convert_dspr2;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    dspr2fct = jsimd_extxbgr_gray_convert_dspr2;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    dspr2fct = jsimd_extxrgb_gray_convert_dspr2;
-    break;
-  default:
-    dspr2fct = jsimd_extrgb_gray_convert_dspr2;
-    break;
-  }
-
-  dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                      JDIMENSION input_row, JSAMPARRAY output_buf,
-                      int num_rows)
-{
-  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    dspr2fct = jsimd_ycc_extrgbx_convert_dspr2;
-    break;
-  case JCS_EXT_BGR:
-    dspr2fct = jsimd_ycc_extbgr_convert_dspr2;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    dspr2fct = jsimd_ycc_extbgrx_convert_dspr2;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    dspr2fct = jsimd_ycc_extxbgr_convert_dspr2;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    dspr2fct = jsimd_ycc_extxrgb_convert_dspr2;
-    break;
-  default:
-    dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
-    break;
-  }
-
-  dspr2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                         JDIMENSION input_row, JSAMPARRAY output_buf,
-                         int num_rows)
-{
-}
-
-GLOBAL(void)
-jsimd_c_null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                     JSAMPIMAGE output_buf, JDIMENSION output_row,
-                     int num_rows)
-{
-  jsimd_c_null_convert_dspr2(cinfo->image_width, input_buf, output_buf,
-                             output_row, num_rows, cinfo->num_components);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_smooth_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (DCTSIZE != 8)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v2_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
-                              compptr->v_samp_factor, compptr->width_in_blocks,
-                              input_data, output_data);
-}
-
-GLOBAL(void)
-jsimd_h2v2_smooth_downsample(j_compress_ptr cinfo,
-                             jpeg_component_info *compptr,
-                             JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v2_smooth_downsample_dspr2(input_data, output_data,
-                                     compptr->v_samp_factor,
-                                     cinfo->max_v_samp_factor,
-                                     cinfo->smoothing_factor,
-                                     compptr->width_in_blocks,
-                                     cinfo->image_width);
-}
-
-GLOBAL(void)
-jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v1_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
-                              compptr->v_samp_factor, compptr->width_in_blocks,
-                              input_data, output_data);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_int_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v2_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
-                            input_data, output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v1_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
-                            input_data, output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                   JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
-
-  jsimd_int_upsample_dspr2(upsample->h_expand[compptr->component_index],
-                           upsample->v_expand[compptr->component_index],
-                           input_data, output_data_ptr, cinfo->output_width,
-                           cinfo->max_v_samp_factor);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_fancy_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_fancy_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v2_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
-                                  compptr->downsampled_width, input_data,
-                                  output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v1_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
-                                  compptr->downsampled_width, input_data,
-                                  output_data_ptr);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_merged_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_merged_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    dspr2fct = jsimd_h2v2_extrgbx_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_BGR:
-    dspr2fct = jsimd_h2v2_extbgr_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    dspr2fct = jsimd_h2v2_extbgrx_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    dspr2fct = jsimd_h2v2_extxbgr_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    dspr2fct = jsimd_h2v2_extxrgb_merged_upsample_dspr2;
-    break;
-  default:
-    dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
-    break;
-  }
-
-  dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
-           cinfo->sample_range_limit);
-}
-
-GLOBAL(void)
-jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    dspr2fct = jsimd_h2v1_extrgbx_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_BGR:
-    dspr2fct = jsimd_h2v1_extbgr_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    dspr2fct = jsimd_h2v1_extbgrx_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    dspr2fct = jsimd_h2v1_extxbgr_merged_upsample_dspr2;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    dspr2fct = jsimd_h2v1_extxrgb_merged_upsample_dspr2;
-    break;
-  default:
-    dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
-    break;
-  }
-
-  dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
-           cinfo->sample_range_limit);
-}
-
-GLOBAL(int)
-jsimd_can_convsamp(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_convsamp_float(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
-               DCTELEM *workspace)
-{
-  jsimd_convsamp_dspr2(sample_data, start_col, workspace);
-}
-
-GLOBAL(void)
-jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
-                     FAST_FLOAT *workspace)
-{
-  jsimd_convsamp_float_dspr2(sample_data, start_col, workspace);
-}
-
-GLOBAL(int)
-jsimd_can_fdct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_ifast(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_fdct_islow(DCTELEM *data)
-{
-  jsimd_fdct_islow_dspr2(data);
-}
-
-GLOBAL(void)
-jsimd_fdct_ifast(DCTELEM *data)
-{
-  jsimd_fdct_ifast_dspr2(data);
-}
-
-GLOBAL(void)
-jsimd_fdct_float(FAST_FLOAT *data)
-{
-}
-
-GLOBAL(int)
-jsimd_can_quantize(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_quantize_float(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
-{
-  jsimd_quantize_dspr2(coef_block, divisors, workspace);
-}
-
-GLOBAL(void)
-jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
-                     FAST_FLOAT *workspace)
-{
-  jsimd_quantize_float_dspr2(coef_block, divisors, workspace);
-}
-
-GLOBAL(int)
-jsimd_can_idct_2x2(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_4x4(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_6x6(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_12x12(void)
-{
-  init_simd();
-
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-  jsimd_idct_2x2_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
-}
-
-GLOBAL(void)
-jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-  int workspace[DCTSIZE * 4]; /* buffers data between passes */
-
-  jsimd_idct_4x4_dspr2(compptr->dct_table, coef_block, output_buf, output_col,
-                       workspace);
-}
-
-GLOBAL(void)
-jsimd_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-  jsimd_idct_6x6_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
-}
-
-GLOBAL(void)
-jsimd_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  int workspace[96];
-  int output[12] = {
-    (int)(output_buf[0] + output_col),
-    (int)(output_buf[1] + output_col),
-    (int)(output_buf[2] + output_col),
-    (int)(output_buf[3] + output_col),
-    (int)(output_buf[4] + output_col),
-    (int)(output_buf[5] + output_col),
-    (int)(output_buf[6] + output_col),
-    (int)(output_buf[7] + output_col),
-    (int)(output_buf[8] + output_col),
-    (int)(output_buf[9] + output_col),
-    (int)(output_buf[10] + output_col),
-    (int)(output_buf[11] + output_col)
-  };
-
-  jsimd_idct_12x12_pass1_dspr2(coef_block, compptr->dct_table, workspace);
-  jsimd_idct_12x12_pass2_dspr2(workspace, output);
-}
-
-GLOBAL(int)
-jsimd_can_idct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(ISLOW_MULT_TYPE) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_ifast(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(IFAST_MULT_TYPE) != 2)
-    return 0;
-  if (IFAST_SCALE_BITS != 2)
-    return 0;
-
-  if (simd_support & JSIMD_DSPR2)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  int output[8] = {
-    (int)(output_buf[0] + output_col),
-    (int)(output_buf[1] + output_col),
-    (int)(output_buf[2] + output_col),
-    (int)(output_buf[3] + output_col),
-    (int)(output_buf[4] + output_col),
-    (int)(output_buf[5] + output_col),
-    (int)(output_buf[6] + output_col),
-    (int)(output_buf[7] + output_col)
-  };
-
-  jsimd_idct_islow_dspr2(coef_block, compptr->dct_table, output,
-                         IDCT_range_limit(cinfo));
-}
-
-GLOBAL(void)
-jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  JCOEFPTR inptr;
-  IFAST_MULT_TYPE *quantptr;
-  DCTELEM workspace[DCTSIZE2];  /* buffers data between passes */
-
-  /* Pass 1: process columns from input, store into work array. */
-
-  inptr = coef_block;
-  quantptr = (IFAST_MULT_TYPE *)compptr->dct_table;
-
-  jsimd_idct_ifast_cols_dspr2(inptr, quantptr, workspace,
-                              mips_idct_ifast_coefs);
-
-  /* Pass 2: process rows from work array, store into output array. */
-  /* Note that we must descale the results by a factor of 8 == 2**3, */
-  /* and also undo the PASS1_BITS scaling. */
-
-  jsimd_idct_ifast_rows_dspr2(workspace, output_buf, output_col,
-                              mips_idct_ifast_coefs);
-}
-
-GLOBAL(void)
-jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-}
-
-GLOBAL(int)
-jsimd_can_huff_encode_one_block(void)
-{
-  return 0;
-}
-
-GLOBAL(JOCTET *)
-jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
-                            int last_dc_val, c_derived_tbl *dctbl,
-                            c_derived_tbl *actbl)
-{
-  return NULL;
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_first_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
-                                  const int *jpeg_natural_order_start, int Sl,
-                                  int Al, JCOEF *values, size_t *zerobits)
-{
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_refine_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
-                                   const int *jpeg_natural_order_start, int Sl,
-                                   int Al, JCOEF *absvalues, size_t *bits)
-{
-  return 0;
-}
diff --git a/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2.S b/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2.S
deleted file mode 100644
index 2ec543e..0000000
--- a/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2.S
+++ /dev/null
@@ -1,4471 +0,0 @@
-/*
- * MIPS DSPr2 optimizations for libjpeg-turbo
- *
- * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
- *                          All Rights Reserved.
- * Authors:  Teodora Novkovic <teodora.novkovic@imgtec.com>
- *           Darko Laus       <darko.laus@imgtec.com>
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#include "jsimd_dspr2_asm.h"
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_c_null_convert_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = input_buf
- * a2     = output_buf
- * a3     = output_row
- * 16(sp) = num_rows
- * 20(sp) = cinfo->num_components
- *
- * Null conversion for compression
- */
-    SAVE_REGS_ON_STACK 8, s0, s1
-
-    lw          t9, 24(sp)      // t9 = num_rows
-    lw          s0, 28(sp)      // s0 = cinfo->num_components
-    andi        t0, a0, 3       // t0 = cinfo->image_width & 3
-    beqz        t0, 4f          // no residual
-     nop
-0:
-    addiu       t9, t9, -1
-    bltz        t9, 7f
-     li         t1, 0
-1:
-    sll         t3, t1, 2
-    lwx         t5, t3(a2)      // t5 = outptr = output_buf[ci]
-    lw          t2, 0(a1)       // t2 = inptr = *input_buf
-    sll         t4, a3, 2
-    lwx         t5, t4(t5)      // t5 = outptr = output_buf[ci][output_row]
-    addu        t2, t2, t1
-    addu        s1, t5, a0
-    addu        t6, t5, t0
-2:
-    lbu         t3, 0(t2)
-    addiu       t5, t5, 1
-    sb          t3, -1(t5)
-    bne         t6, t5, 2b
-     addu       t2, t2, s0
-3:
-    lbu         t3, 0(t2)
-    addu        t4, t2, s0
-    addu        t7, t4, s0
-    addu        t8, t7, s0
-    addu        t2, t8, s0
-    lbu         t4, 0(t4)
-    lbu         t7, 0(t7)
-    lbu         t8, 0(t8)
-    addiu       t5, t5, 4
-    sb          t3, -4(t5)
-    sb          t4, -3(t5)
-    sb          t7, -2(t5)
-    bne         s1, t5, 3b
-     sb         t8, -1(t5)
-    addiu       t1, t1, 1
-    bne         t1, s0, 1b
-     nop
-    addiu       a1, a1, 4
-    bgez        t9, 0b
-     addiu      a3, a3, 1
-    b           7f
-     nop
-4:
-    addiu       t9, t9, -1
-    bltz        t9, 7f
-     li         t1, 0
-5:
-    sll         t3, t1, 2
-    lwx         t5, t3(a2)      // t5 = outptr = output_buf[ci]
-    lw          t2, 0(a1)       // t2 = inptr = *input_buf
-    sll         t4, a3, 2
-    lwx         t5, t4(t5)      // t5 = outptr = output_buf[ci][output_row]
-    addu        t2, t2, t1
-    addu        s1, t5, a0
-    addu        t6, t5, t0
-6:
-    lbu         t3, 0(t2)
-    addu        t4, t2, s0
-    addu        t7, t4, s0
-    addu        t8, t7, s0
-    addu        t2, t8, s0
-    lbu         t4, 0(t4)
-    lbu         t7, 0(t7)
-    lbu         t8, 0(t8)
-    addiu       t5, t5, 4
-    sb          t3, -4(t5)
-    sb          t4, -3(t5)
-    sb          t7, -2(t5)
-    bne         s1, t5, 6b
-     sb         t8, -1(t5)
-    addiu       t1, t1, 1
-    bne         t1, s0, 5b
-     nop
-    addiu       a1, a1, 4
-    bgez        t9, 4b
-     addiu      a3, a3, 1
-7:
-    RESTORE_REGS_FROM_STACK 8, s0, s1
-
-    j           ra
-     nop
-
-END(jsimd_c_null_convert_dspr2)
-
-
-/*****************************************************************************/
-/*
- * jsimd_extrgb_ycc_convert_dspr2
- * jsimd_extbgr_ycc_convert_dspr2
- * jsimd_extrgbx_ycc_convert_dspr2
- * jsimd_extbgrx_ycc_convert_dspr2
- * jsimd_extxbgr_ycc_convert_dspr2
- * jsimd_extxrgb_ycc_convert_dspr2
- *
- * Colorspace conversion RGB -> YCbCr
- */
-
-.macro GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2  colorid, pixel_size, \
-                                             r_offs, g_offs, b_offs
-
-.macro DO_RGB_TO_YCC  r, g, b, inptr
-    lbu         \r, \r_offs(\inptr)
-    lbu         \g, \g_offs(\inptr)
-    lbu         \b, \b_offs(\inptr)
-    addiu       \inptr, \pixel_size
-.endm
-
-LEAF_DSPR2(jsimd_\colorid\()_ycc_convert_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = input_buf
- * a2     = output_buf
- * a3     = output_row
- * 16(sp) = num_rows
- */
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    lw          t7, 48(sp)      // t7 = num_rows
-    li          s0, 0x4c8b      // FIX(0.29900)
-    li          s1, 0x9646      // FIX(0.58700)
-    li          s2, 0x1d2f      // FIX(0.11400)
-    li          s3, 0xffffd4cd  // -FIX(0.16874)
-    li          s4, 0xffffab33  // -FIX(0.33126)
-    li          s5, 0x8000      // FIX(0.50000)
-    li          s6, 0xffff94d1  // -FIX(0.41869)
-    li          s7, 0xffffeb2f  // -FIX(0.08131)
-    li          t8, 0x807fff    // CBCR_OFFSET + ONE_HALF-1
-
-0:
-    addiu       t7, -1          // --num_rows
-    lw          t6, 0(a1)       // t6 = input_buf[0]
-    lw          t0, 0(a2)
-    lw          t1, 4(a2)
-    lw          t2, 8(a2)
-    sll         t3, a3, 2
-    lwx         t0, t3(t0)      // t0 = output_buf[0][output_row]
-    lwx         t1, t3(t1)      // t1 = output_buf[1][output_row]
-    lwx         t2, t3(t2)      // t2 = output_buf[2][output_row]
-
-    addu        t9, t2, a0      // t9 = end address
-    addiu       a3, 1
-
-1:
-    DO_RGB_TO_YCC t3, t4, t5, t6
-
-    mtlo        s5, $ac0
-    mtlo        t8, $ac1
-    mtlo        t8, $ac2
-    maddu       $ac0, s2, t5
-    maddu       $ac1, s5, t5
-    maddu       $ac2, s5, t3
-    maddu       $ac0, s0, t3
-    maddu       $ac1, s3, t3
-    maddu       $ac2, s6, t4
-    maddu       $ac0, s1, t4
-    maddu       $ac1, s4, t4
-    maddu       $ac2, s7, t5
-    extr.w      t3, $ac0, 16
-    extr.w      t4, $ac1, 16
-    extr.w      t5, $ac2, 16
-    sb          t3, 0(t0)
-    sb          t4, 0(t1)
-    sb          t5, 0(t2)
-    addiu       t0, 1
-    addiu       t2, 1
-    bne         t2, t9, 1b
-     addiu      t1, 1
-    bgtz        t7, 0b
-     addiu      a1, 4
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-END(jsimd_\colorid\()_ycc_convert_dspr2)
-
-.purgem DO_RGB_TO_YCC
-
-.endm
-
-/*-------------------------------------id -- pix R  G  B */
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extrgb,  3, 0, 1, 2
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extbgr,  3, 2, 1, 0
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extrgbx, 4, 0, 1, 2
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extbgrx, 4, 2, 1, 0
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extxbgr, 4, 3, 2, 1
-GENERATE_JSIMD_RGB_YCC_CONVERT_DSPR2 extxrgb, 4, 1, 2, 3
-
-
-/*****************************************************************************/
-/*
- * jsimd_ycc_extrgb_convert_dspr2
- * jsimd_ycc_extbgr_convert_dspr2
- * jsimd_ycc_extrgbx_convert_dspr2
- * jsimd_ycc_extbgrx_convert_dspr2
- * jsimd_ycc_extxbgr_convert_dspr2
- * jsimd_ycc_extxrgb_convert_dspr2
- *
- * Colorspace conversion YCbCr -> RGB
- */
-
-.macro GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2  colorid, pixel_size, \
-                                             r_offs, g_offs, b_offs, a_offs
-
-.macro STORE_YCC_TO_RGB  scratch0 scratch1 scratch2 outptr
-    sb          \scratch0, \r_offs(\outptr)
-    sb          \scratch1, \g_offs(\outptr)
-    sb          \scratch2, \b_offs(\outptr)
-.if (\pixel_size == 4)
-    li          t0, 0xFF
-    sb          t0, \a_offs(\outptr)
-.endif
-    addiu       \outptr, \pixel_size
-.endm
-
-LEAF_DSPR2(jsimd_ycc_\colorid\()_convert_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = input_buf
- * a2     = input_row
- * a3     = output_buf
- * 16(sp) = num_rows
- */
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    lw          s1, 48(sp)
-    li          t3, 0x8000
-    li          t4, 0x166e9     // FIX(1.40200)
-    li          t5, 0x1c5a2     // FIX(1.77200)
-    li          t6, 0xffff492e  // -FIX(0.71414)
-    li          t7, 0xffffa7e6  // -FIX(0.34414)
-    repl.ph     t8, 128
-
-0:
-    lw          s0, 0(a3)
-    lw          t0, 0(a1)
-    lw          t1, 4(a1)
-    lw          t2, 8(a1)
-    sll         s5, a2, 2
-    addiu       s1, -1
-    lwx         s2, s5(t0)
-    lwx         s3, s5(t1)
-    lwx         s4, s5(t2)
-    addu        t9, s2, a0
-    addiu       a2, 1
-
-1:
-    lbu         s7, 0(s4)       // cr
-    lbu         s6, 0(s3)       // cb
-    lbu         s5, 0(s2)       // y
-    addiu       s2, 1
-    addiu       s4, 1
-    addiu       s7, -128
-    addiu       s6, -128
-    mul         t2, t7, s6
-    mul         t0, t6, s7      // Crgtab[cr]
-    sll         s7, 15
-    mulq_rs.w   t1, t4, s7      // Crrtab[cr]
-    sll         s6, 15
-    addu        t2, t3          // Cbgtab[cb]
-    addu        t2, t0
-
-    mulq_rs.w   t0, t5, s6      // Cbbtab[cb]
-    sra         t2, 16
-    addu        t1, s5
-    addu        t2, s5          // add y
-    ins         t2, t1, 16, 16
-    subu.ph     t2, t2, t8
-    addu        t0, s5
-    shll_s.ph   t2, t2, 8
-    subu        t0, 128
-    shra.ph     t2, t2, 8
-    shll_s.w    t0, t0, 24
-    addu.ph     t2, t2, t8      // clip & store
-    sra         t0, t0, 24
-    sra         t1, t2, 16
-    addiu       t0, 128
-
-    STORE_YCC_TO_RGB t1, t2, t0, s0
-
-    bne         s2, t9, 1b
-     addiu      s3, 1
-    bgtz        s1, 0b
-     addiu      a3, 4
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-END(jsimd_ycc_\colorid\()_convert_dspr2)
-
-.purgem STORE_YCC_TO_RGB
-
-.endm
-
-/*-------------------------------------id -- pix R  G  B  A */
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extrgb,  3, 0, 1, 2, 3
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extbgr,  3, 2, 1, 0, 3
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extrgbx, 4, 0, 1, 2, 3
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extbgrx, 4, 2, 1, 0, 3
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extxbgr, 4, 3, 2, 1, 0
-GENERATE_JSIMD_YCC_RGB_CONVERT_DSPR2 extxrgb, 4, 1, 2, 3, 0
-
-
-/*****************************************************************************/
-/*
- * jsimd_extrgb_gray_convert_dspr2
- * jsimd_extbgr_gray_convert_dspr2
- * jsimd_extrgbx_gray_convert_dspr2
- * jsimd_extbgrx_gray_convert_dspr2
- * jsimd_extxbgr_gray_convert_dspr2
- * jsimd_extxrgb_gray_convert_dspr2
- *
- * Colorspace conversion RGB -> GRAY
- */
-
-.macro GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2  colorid, pixel_size, \
-                                              r_offs, g_offs, b_offs
-
-.macro DO_RGB_TO_GRAY  r, g, b, inptr
-    lbu         \r, \r_offs(\inptr)
-    lbu         \g, \g_offs(\inptr)
-    lbu         \b, \b_offs(\inptr)
-    addiu       \inptr, \pixel_size
-.endm
-
-LEAF_DSPR2(jsimd_\colorid\()_gray_convert_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = input_buf
- * a2     = output_buf
- * a3     = output_row
- * 16(sp) = num_rows
- */
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    li          s0, 0x4c8b      // s0 = FIX(0.29900)
-    li          s1, 0x9646      // s1 = FIX(0.58700)
-    li          s2, 0x1d2f      // s2 = FIX(0.11400)
-    li          s7, 0x8000      // s7 = FIX(0.50000)
-    lw          s6, 48(sp)
-    andi        t7, a0, 3
-
-0:
-    addiu       s6, -1          // s6 = num_rows
-    lw          t0, 0(a1)
-    lw          t1, 0(a2)
-    sll         t3, a3, 2
-    lwx         t1, t3(t1)
-    addiu       a3, 1
-    addu        t9, t1, a0
-    subu        t8, t9, t7
-    beq         t1, t8, 2f
-     nop
-
-1:
-    DO_RGB_TO_GRAY t3, t4, t5, t0
-    DO_RGB_TO_GRAY s3, s4, s5, t0
-
-    mtlo        s7, $ac0
-    maddu       $ac0, s2, t5
-    maddu       $ac0, s1, t4
-    maddu       $ac0, s0, t3
-    mtlo        s7, $ac1
-    maddu       $ac1, s2, s5
-    maddu       $ac1, s1, s4
-    maddu       $ac1, s0, s3
-    extr.w      t6, $ac0, 16
-
-    DO_RGB_TO_GRAY t3, t4, t5, t0
-    DO_RGB_TO_GRAY s3, s4, s5, t0
-
-    mtlo        s7, $ac0
-    maddu       $ac0, s2, t5
-    maddu       $ac0, s1, t4
-    extr.w      t2, $ac1, 16
-    maddu       $ac0, s0, t3
-    mtlo        s7, $ac1
-    maddu       $ac1, s2, s5
-    maddu       $ac1, s1, s4
-    maddu       $ac1, s0, s3
-    extr.w      t5, $ac0, 16
-    sb          t6, 0(t1)
-    sb          t2, 1(t1)
-    extr.w      t3, $ac1, 16
-    addiu       t1, 4
-    sb          t5, -2(t1)
-    sb          t3, -1(t1)
-    bne         t1, t8, 1b
-     nop
-
-2:
-    beqz        t7, 4f
-     nop
-
-3:
-    DO_RGB_TO_GRAY t3, t4, t5, t0
-
-    mtlo        s7, $ac0
-    maddu       $ac0, s2, t5
-    maddu       $ac0, s1, t4
-    maddu       $ac0, s0, t3
-    extr.w      t6, $ac0, 16
-    sb          t6, 0(t1)
-    addiu       t1, 1
-    bne         t1, t9, 3b
-     nop
-
-4:
-    bgtz        s6, 0b
-     addiu      a1, 4
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-END(jsimd_\colorid\()_gray_convert_dspr2)
-
-.purgem DO_RGB_TO_GRAY
-
-.endm
-
-/*-------------------------------------id --  pix R  G  B */
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extrgb,  3, 0, 1, 2
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extbgr,  3, 2, 1, 0
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extrgbx, 4, 0, 1, 2
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extbgrx, 4, 2, 1, 0
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extxbgr, 4, 3, 2, 1
-GENERATE_JSIMD_RGB_GRAY_CONVERT_DSPR2 extxrgb, 4, 1, 2, 3
-
-
-/*****************************************************************************/
-/*
- * jsimd_h2v2_merged_upsample_dspr2
- * jsimd_h2v2_extrgb_merged_upsample_dspr2
- * jsimd_h2v2_extrgbx_merged_upsample_dspr2
- * jsimd_h2v2_extbgr_merged_upsample_dspr2
- * jsimd_h2v2_extbgrx_merged_upsample_dspr2
- * jsimd_h2v2_extxbgr_merged_upsample_dspr2
- * jsimd_h2v2_extxrgb_merged_upsample_dspr2
- *
- * Merged h2v2 upsample routines
- */
-.macro GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2  colorid, pixel_size, \
-                                            r1_offs, g1_offs, \
-                                            b1_offs, a1_offs, \
-                                            r2_offs, g2_offs, \
-                                            b2_offs, a2_offs
-
-.macro STORE_H2V2_2_PIXELS  scratch0 scratch1 scratch2 scratch3 scratch4 \
-                            scratch5 outptr
-    sb          \scratch0, \r1_offs(\outptr)
-    sb          \scratch1, \g1_offs(\outptr)
-    sb          \scratch2, \b1_offs(\outptr)
-    sb          \scratch3, \r2_offs(\outptr)
-    sb          \scratch4, \g2_offs(\outptr)
-    sb          \scratch5, \b2_offs(\outptr)
-.if (\pixel_size == 8)
-    li          \scratch0, 0xFF
-    sb          \scratch0, \a1_offs(\outptr)
-    sb          \scratch0, \a2_offs(\outptr)
-.endif
-    addiu       \outptr, \pixel_size
-.endm
-
-.macro STORE_H2V2_1_PIXEL  scratch0 scratch1 scratch2 outptr
-    sb          \scratch0, \r1_offs(\outptr)
-    sb          \scratch1, \g1_offs(\outptr)
-    sb          \scratch2, \b1_offs(\outptr)
-
-.if (\pixel_size == 8)
-    li          t0, 0xFF
-    sb          t0, \a1_offs(\outptr)
-.endif
-.endm
-
-LEAF_DSPR2(jsimd_h2v2_\colorid\()_merged_upsample_dspr2)
-/*
- * a0     = cinfo->output_width
- * a1     = input_buf
- * a2     = in_row_group_ctr
- * a3     = output_buf
- * 16(sp) = cinfo->sample_range_limit
- */
-    SAVE_REGS_ON_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, ra
-
-    lw          t9, 56(sp)      // cinfo->sample_range_limit
-    lw          v0, 0(a1)
-    lw          v1, 4(a1)
-    lw          t0, 8(a1)
-    sll         t1, a2, 3
-    addiu       t2, t1, 4
-    sll         t3, a2, 2
-    lw          t4, 0(a3)       // t4 = output_buf[0]
-    lwx         t1, t1(v0)      // t1 = input_buf[0][in_row_group_ctr*2]
-    lwx         t2, t2(v0)      // t2 = input_buf[0][in_row_group_ctr*2 + 1]
-    lwx         t5, t3(v1)      // t5 = input_buf[1][in_row_group_ctr]
-    lwx         t6, t3(t0)      // t6 = input_buf[2][in_row_group_ctr]
-    lw          t7, 4(a3)       // t7 = output_buf[1]
-    li          s1, 0xe6ea
-    addiu       t8, s1, 0x7fff    // t8 = 0x166e9 [FIX(1.40200)]
-    addiu       s0, t8, 0x5eb9    // s0 = 0x1c5a2 [FIX(1.77200)]
-    addiu       s1, zero, 0xa7e6  // s4 = 0xffffa7e6 [-FIX(0.34414)]
-    xori        s2, s1, 0xeec8    // s3 = 0xffff492e [-FIX(0.71414)]
-    srl         t3, a0, 1
-    blez        t3, 2f
-     addu       t0, t5, t3      // t0 = end address
- 1:
-    lbu         t3, 0(t5)
-    lbu         s3, 0(t6)
-    addiu       t5, t5, 1
-    addiu       t3, t3, -128    // (cb - 128)
-    addiu       s3, s3, -128    // (cr - 128)
-    mult        $ac1, s1, t3
-    madd        $ac1, s2, s3
-    sll         s3, s3, 15
-    sll         t3, t3, 15
-    mulq_rs.w   s4, t8, s3      // s4 = (C1 * cr + ONE_HALF)>> SCALEBITS
-    extr_r.w    s5, $ac1, 16
-    mulq_rs.w   s6, s0, t3      // s6 = (C2 * cb + ONE_HALF)>> SCALEBITS
-    lbu         v0, 0(t1)
-    addiu       t6, t6, 1
-    addiu       t1, t1, 2
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         AT, 0(t3)
-    lbu         s7, 0(s3)
-    lbu         ra, 0(v1)
-    lbu         v0, -1(t1)
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         t3, 0(t3)
-    lbu         s3, 0(s3)
-    lbu         v1, 0(v1)
-    lbu         v0, 0(t2)
-
-    STORE_H2V2_2_PIXELS AT, s7, ra, t3, s3, v1, t4
-
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         AT, 0(t3)
-    lbu         s7, 0(s3)
-    lbu         ra, 0(v1)
-    lbu         v0, 1(t2)
-    addiu       t2, t2, 2
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         t3, 0(t3)
-    lbu         s3, 0(s3)
-    lbu         v1, 0(v1)
-
-    STORE_H2V2_2_PIXELS AT, s7, ra, t3, s3, v1, t7
-
-    bne         t0, t5, 1b
-     nop
-2:
-    andi        t0, a0, 1
-    beqz        t0, 4f
-     lbu        t3, 0(t5)
-    lbu         s3, 0(t6)
-    addiu       t3, t3, -128    // (cb - 128)
-    addiu       s3, s3, -128    // (cr - 128)
-    mult        $ac1, s1, t3
-    madd        $ac1, s2, s3
-    sll         s3, s3, 15
-    sll         t3, t3, 15
-    lbu         v0, 0(t1)
-    extr_r.w    s5, $ac1, 16
-    mulq_rs.w   s4, t8, s3      // s4 = (C1 * cr + ONE_HALF)>> SCALEBITS
-    mulq_rs.w   s6, s0, t3      // s6 = (C2 * cb + ONE_HALF)>> SCALEBITS
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         t3, 0(t3)
-    lbu         s3, 0(s3)
-    lbu         v1, 0(v1)
-    lbu         v0, 0(t2)
-
-    STORE_H2V2_1_PIXEL t3, s3, v1, t4
-
-    addu        t3, v0, s4      // y+cred
-    addu        s3, v0, s5      // y+cgreen
-    addu        v1, v0, s6      // y+cblue
-    addu        t3, t9, t3      // y+cred
-    addu        s3, t9, s3      // y+cgreen
-    addu        v1, t9, v1      // y+cblue
-    lbu         t3, 0(t3)
-    lbu         s3, 0(s3)
-    lbu         v1, 0(v1)
-
-    STORE_H2V2_1_PIXEL t3, s3, v1, t7
-4:
-    RESTORE_REGS_FROM_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, ra
-
-    j           ra
-     nop
-
-END(jsimd_h2v2_\colorid\()_merged_upsample_dspr2)
-
-.purgem STORE_H2V2_1_PIXEL
-.purgem STORE_H2V2_2_PIXELS
-.endm
-
-/*------------------------------------id -- pix R1 G1 B1 A1 R2 G2 B2 A2 */
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extrgb,  6, 0, 1, 2, 6, 3, 4, 5, 6
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extbgr,  6, 2, 1, 0, 3, 5, 4, 3, 6
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extrgbx, 8, 0, 1, 2, 3, 4, 5, 6, 7
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extbgrx, 8, 2, 1, 0, 3, 6, 5, 4, 7
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extxbgr, 8, 3, 2, 1, 0, 7, 6, 5, 4
-GENERATE_H2V2_MERGED_UPSAMPLE_DSPR2 extxrgb, 8, 1, 2, 3, 0, 5, 6, 7, 4
-
-
-/*****************************************************************************/
-/*
- * jsimd_h2v1_merged_upsample_dspr2
- * jsimd_h2v1_extrgb_merged_upsample_dspr2
- * jsimd_h2v1_extrgbx_merged_upsample_dspr2
- * jsimd_h2v1_extbgr_merged_upsample_dspr2
- * jsimd_h2v1_extbgrx_merged_upsample_dspr2
- * jsimd_h2v1_extxbgr_merged_upsample_dspr2
- * jsimd_h2v1_extxrgb_merged_upsample_dspr2
- *
- * Merged h2v1 upsample routines
- */
-
-.macro GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2  colorid, pixel_size, \
-                                            r1_offs, g1_offs, \
-                                            b1_offs, a1_offs, \
-                                            r2_offs, g2_offs, \
-                                            b2_offs, a2_offs
-
-.macro STORE_H2V1_2_PIXELS  scratch0 scratch1 scratch2 scratch3 scratch4 \
-                            scratch5 outptr
-    sb          \scratch0, \r1_offs(\outptr)
-    sb          \scratch1, \g1_offs(\outptr)
-    sb          \scratch2, \b1_offs(\outptr)
-    sb          \scratch3, \r2_offs(\outptr)
-    sb          \scratch4, \g2_offs(\outptr)
-    sb          \scratch5, \b2_offs(\outptr)
-.if (\pixel_size == 8)
-    li          t0, 0xFF
-    sb          t0, \a1_offs(\outptr)
-    sb          t0, \a2_offs(\outptr)
-.endif
-    addiu       \outptr, \pixel_size
-.endm
-
-.macro STORE_H2V1_1_PIXEL  scratch0 scratch1 scratch2 outptr
-    sb          \scratch0, \r1_offs(\outptr)
-    sb          \scratch1, \g1_offs(\outptr)
-    sb          \scratch2, \b1_offs(\outptr)
-.if (\pixel_size == 8)
-    li          t0, 0xFF
-    sb          t0, \a1_offs(\outptr)
-.endif
-.endm
-
-LEAF_DSPR2(jsimd_h2v1_\colorid\()_merged_upsample_dspr2)
-/*
- * a0     = cinfo->output_width
- * a1     = input_buf
- * a2     = in_row_group_ctr
- * a3     = output_buf
- * 16(sp) = range_limit
- */
-    SAVE_REGS_ON_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, ra
-
-    li          t0, 0xe6ea
-    lw          t1, 0(a1)         // t1 = input_buf[0]
-    lw          t2, 4(a1)         // t2 = input_buf[1]
-    lw          t3, 8(a1)         // t3 = input_buf[2]
-    lw          t8, 56(sp)        // t8 = range_limit
-    addiu       s1, t0, 0x7fff    // s1 = 0x166e9 [FIX(1.40200)]
-    addiu       s2, s1, 0x5eb9    // s2 = 0x1c5a2 [FIX(1.77200)]
-    addiu       s0, t0, 0x9916    // s0 = 0x8000
-    addiu       s4, zero, 0xa7e6  // s4 = 0xffffa7e6 [-FIX(0.34414)]
-    xori        s3, s4, 0xeec8    // s3 = 0xffff492e [-FIX(0.71414)]
-    srl         t0, a0, 1
-    sll         t4, a2, 2
-    lwx         s5, t4(t1)      // s5 = inptr0
-    lwx         s6, t4(t2)      // s6 = inptr1
-    lwx         s7, t4(t3)      // s7 = inptr2
-    lw          t7, 0(a3)       // t7 = outptr
-    blez        t0, 2f
-     addu       t9, s6, t0      // t9 = end address
-1:
-    lbu         t2, 0(s6)       // t2 = cb
-    lbu         t0, 0(s7)       // t0 = cr
-    lbu         t1, 0(s5)       // t1 = y
-    addiu       t2, t2, -128    // t2 = cb - 128
-    addiu       t0, t0, -128    // t0 = cr - 128
-    mult        $ac1, s4, t2
-    madd        $ac1, s3, t0
-    sll         t0, t0, 15
-    sll         t2, t2, 15
-    mulq_rs.w   t0, s1, t0      // t0 = (C1*cr + ONE_HALF)>> SCALEBITS
-    extr_r.w    t5, $ac1, 16
-    mulq_rs.w   t6, s2, t2      // t6 = (C2*cb + ONE_HALF)>> SCALEBITS
-    addiu       s7, s7, 1
-    addiu       s6, s6, 1
-    addu        t2, t1, t0      // t2 = y + cred
-    addu        t3, t1, t5      // t3 = y + cgreen
-    addu        t4, t1, t6      // t4 = y + cblue
-    addu        t2, t8, t2
-    addu        t3, t8, t3
-    addu        t4, t8, t4
-    lbu         t1, 1(s5)
-    lbu         v0, 0(t2)
-    lbu         v1, 0(t3)
-    lbu         ra, 0(t4)
-    addu        t2, t1, t0
-    addu        t3, t1, t5
-    addu        t4, t1, t6
-    addu        t2, t8, t2
-    addu        t3, t8, t3
-    addu        t4, t8, t4
-    lbu         t2, 0(t2)
-    lbu         t3, 0(t3)
-    lbu         t4, 0(t4)
-
-    STORE_H2V1_2_PIXELS v0, v1, ra, t2, t3, t4, t7
-
-    bne         t9, s6, 1b
-     addiu      s5, s5, 2
-2:
-    andi        t0, a0, 1
-    beqz        t0, 4f
-     nop
-3:
-    lbu         t2, 0(s6)
-    lbu         t0, 0(s7)
-    lbu         t1, 0(s5)
-    addiu       t2, t2, -128    // (cb - 128)
-    addiu       t0, t0, -128    // (cr - 128)
-    mul         t3, s4, t2
-    mul         t4, s3, t0
-    sll         t0, t0, 15
-    sll         t2, t2, 15
-    mulq_rs.w   t0, s1, t0      // (C1*cr + ONE_HALF)>> SCALEBITS
-    mulq_rs.w   t6, s2, t2      // (C2*cb + ONE_HALF)>> SCALEBITS
-    addu        t3, t3, s0
-    addu        t3, t4, t3
-    sra         t5, t3, 16      // (C4*cb + ONE_HALF + C3*cr)>> SCALEBITS
-    addu        t2, t1, t0      // y + cred
-    addu        t3, t1, t5      // y + cgreen
-    addu        t4, t1, t6      // y + cblue
-    addu        t2, t8, t2
-    addu        t3, t8, t3
-    addu        t4, t8, t4
-    lbu         t2, 0(t2)
-    lbu         t3, 0(t3)
-    lbu         t4, 0(t4)
-
-    STORE_H2V1_1_PIXEL t2, t3, t4, t7
-4:
-    RESTORE_REGS_FROM_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, ra
-
-    j           ra
-     nop
-
-END(jsimd_h2v1_\colorid\()_merged_upsample_dspr2)
-
-.purgem STORE_H2V1_1_PIXEL
-.purgem STORE_H2V1_2_PIXELS
-.endm
-
-/*------------------------------------id -- pix R1 G1 B1 A1 R2 G2 B2 A2 */
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extrgb,  6, 0, 1, 2, 6, 3, 4, 5, 6
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extbgr,  6, 2, 1, 0, 3, 5, 4, 3, 6
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extrgbx, 8, 0, 1, 2, 3, 4, 5, 6, 7
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extbgrx, 8, 2, 1, 0, 3, 6, 5, 4, 7
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extxbgr, 8, 3, 2, 1, 0, 7, 6, 5, 4
-GENERATE_H2V1_MERGED_UPSAMPLE_DSPR2 extxrgb, 8, 1, 2, 3, 0, 5, 6, 7, 4
-
-
-/*****************************************************************************/
-/*
- * jsimd_h2v2_fancy_upsample_dspr2
- *
- * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
- */
-LEAF_DSPR2(jsimd_h2v2_fancy_upsample_dspr2)
-/*
- * a0 = cinfo->max_v_samp_factor
- * a1 = downsampled_width
- * a2 = input_data
- * a3 = output_data_ptr
- */
-    SAVE_REGS_ON_STACK 24, s0, s1, s2, s3, s4, s5
-
-    li            s4, 0
-    lw            s2, 0(a3)       // s2 = *output_data_ptr
-0:
-    li            t9, 2
-    lw            s1, -4(a2)      // s1 = inptr1
-
-1:
-    lw            s0, 0(a2)       // s0 = inptr0
-    lwx           s3, s4(s2)
-    addiu         s5, a1, -2      // s5 = downsampled_width - 2
-    srl           t4, s5, 1
-    sll           t4, t4, 1
-    lbu           t0, 0(s0)
-    lbu           t1, 1(s0)
-    lbu           t2, 0(s1)
-    lbu           t3, 1(s1)
-    addiu         s0, 2
-    addiu         s1, 2
-    addu          t8, s0, t4      // t8 = end address
-    andi          s5, s5, 1       // s5 = residual
-    sll           t4, t0, 1
-    sll           t6, t1, 1
-    addu          t0, t0, t4      // t0 = (*inptr0++) * 3
-    addu          t1, t1, t6      // t1 = (*inptr0++) * 3
-    addu          t7, t0, t2      // t7 = thiscolsum
-    addu          t6, t1, t3      // t5 = nextcolsum
-    sll           t0, t7, 2       // t0 = thiscolsum * 4
-    subu          t1, t0, t7      // t1 = thiscolsum * 3
-    shra_r.w      t0, t0, 4
-    addiu         t1, 7
-    addu          t1, t1, t6
-    srl           t1, t1, 4
-    sb            t0, 0(s3)
-    sb            t1, 1(s3)
-    beq           t8, s0, 22f     // skip to final iteration if width == 3
-     addiu        s3, 2
-2:
-    lh            t0, 0(s0)       // t0 = A3|A2
-    lh            t2, 0(s1)       // t2 = B3|B2
-    addiu         s0, 2
-    addiu         s1, 2
-    preceu.ph.qbr t0, t0          // t0 = 0|A3|0|A2
-    preceu.ph.qbr t2, t2          // t2 = 0|B3|0|B2
-    shll.ph       t1, t0, 1
-    sll           t3, t6, 1
-    addu.ph       t0, t1, t0      // t0 = A3*3|A2*3
-    addu          t3, t3, t6      // t3 = this * 3
-    addu.ph       t0, t0, t2      // t0 = next2|next1
-    addu          t1, t3, t7
-    andi          t7, t0, 0xFFFF  // t7 = next1
-    sll           t2, t7, 1
-    addu          t2, t7, t2      // t2 = next1*3
-    addu          t4, t2, t6
-    srl           t6, t0, 16      // t6 = next2
-    shra_r.w      t1, t1, 4       // t1 = (this*3 + last + 8) >> 4
-    addu          t0, t3, t7
-    addiu         t0, 7
-    srl           t0, t0, 4       // t0 = (this*3 + next1 + 7) >> 4
-    shra_r.w      t4, t4, 4       // t3 = (next1*3 + this + 8) >> 4
-    addu          t2, t2, t6
-    addiu         t2, 7
-    srl           t2, t2, 4       // t2 = (next1*3 + next2 + 7) >> 4
-    sb            t1, 0(s3)
-    sb            t0, 1(s3)
-    sb            t4, 2(s3)
-    sb            t2, 3(s3)
-    bne           t8, s0, 2b
-     addiu        s3, 4
-22:
-    beqz          s5, 4f
-     addu         t8, s0, s5
-3:
-    lbu           t0, 0(s0)
-    lbu           t2, 0(s1)
-    addiu         s0, 1
-    addiu         s1, 1
-    sll           t3, t6, 1
-    sll           t1, t0, 1
-    addu          t1, t0, t1      // t1 = inptr0 * 3
-    addu          t3, t3, t6      // t3 = thiscolsum * 3
-    addu          t5, t1, t2
-    addu          t1, t3, t7
-    shra_r.w      t1, t1, 4
-    addu          t0, t3, t5
-    addiu         t0, 7
-    srl           t0, t0, 4
-    sb            t1, 0(s3)
-    sb            t0, 1(s3)
-    addiu         s3, 2
-    move          t7, t6
-    bne           t8, s0, 3b
-     move         t6, t5
-4:
-    sll           t0, t6, 2       // t0 = thiscolsum * 4
-    subu          t1, t0, t6      // t1 = thiscolsum * 3
-    addu          t1, t1, t7
-    addiu         s4, 4
-    shra_r.w      t1, t1, 4
-    addiu         t0, 7
-    srl           t0, t0, 4
-    sb            t1, 0(s3)
-    sb            t0, 1(s3)
-    addiu         t9, -1
-    addiu         s3, 2
-    bnez          t9, 1b
-     lw           s1, 4(a2)
-    srl           t0, s4, 2
-    subu          t0, a0, t0
-    bgtz          t0, 0b
-     addiu        a2, 4
-
-    RESTORE_REGS_FROM_STACK 24, s0, s1, s2, s3, s4, s5
-
-    j             ra
-     nop
-END(jsimd_h2v2_fancy_upsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v1_fancy_upsample_dspr2)
-/*
- * a0 = cinfo->max_v_samp_factor
- * a1 = downsampled_width
- * a2 = input_data
- * a3 = output_data_ptr
- */
-    SAVE_REGS_ON_STACK 16, s0, s1, s2, s3
-
-    .set at
-
-    beqz          a0, 3f
-     sll          t0, a0, 2
-    lw            s1, 0(a3)
-    li            s3, 0x10001
-    addu          s0, s1, t0
-0:
-    addiu         t8, a1, -2
-    srl           t9, t8, 2
-    lw            t7, 0(a2)
-    lw            s2, 0(s1)
-    lbu           t0, 0(t7)
-    lbu           t1, 1(t7)       // t1 = inptr[1]
-    sll           t2, t0, 1
-    addu          t2, t2, t0      // t2 = invalue*3
-    addu          t2, t2, t1
-    shra_r.w      t2, t2, 2
-    sb            t0, 0(s2)
-    sb            t2, 1(s2)
-    beqz          t9, 11f
-     addiu        s2, 2
-1:
-    ulw           t0, 0(t7)       // t0 = |P3|P2|P1|P0|
-    ulw           t1, 1(t7)
-    ulh           t2, 4(t7)       // t2 = |0|0|P5|P4|
-    preceu.ph.qbl t3, t0          // t3 = |0|P3|0|P2|
-    preceu.ph.qbr t0, t0          // t0 = |0|P1|0|P0|
-    preceu.ph.qbr t2, t2          // t2 = |0|P5|0|P4|
-    preceu.ph.qbl t4, t1          // t4 = |0|P4|0|P3|
-    preceu.ph.qbr t1, t1          // t1 = |0|P2|0|P1|
-    shll.ph       t5, t4, 1
-    shll.ph       t6, t1, 1
-    addu.ph       t5, t5, t4      // t5 = |P4*3|P3*3|
-    addu.ph       t6, t6, t1      // t6 = |P2*3|P1*3|
-    addu.ph       t4, t3, s3
-    addu.ph       t0, t0, s3
-    addu.ph       t4, t4, t5
-    addu.ph       t0, t0, t6
-    shrl.ph       t4, t4, 2       // t4 = |0|P3|0|P2|
-    shrl.ph       t0, t0, 2       // t0 = |0|P1|0|P0|
-    addu.ph       t2, t2, t5
-    addu.ph       t3, t3, t6
-    shra_r.ph     t2, t2, 2       // t2 = |0|P5|0|P4|
-    shra_r.ph     t3, t3, 2       // t3 = |0|P3|0|P2|
-    shll.ph       t2, t2, 8
-    shll.ph       t3, t3, 8
-    or            t2, t4, t2
-    or            t3, t3, t0
-    addiu         t9, -1
-    usw           t3, 0(s2)
-    usw           t2, 4(s2)
-    addiu         s2, 8
-    bgtz          t9, 1b
-     addiu        t7, 4
-11:
-    andi          t8, 3
-    beqz          t8, 22f
-     addiu        t7, 1
-
-2:
-    lbu           t0, 0(t7)
-    addiu         t7, 1
-    sll           t1, t0, 1
-    addu          t2, t0, t1      // t2 = invalue
-    lbu           t3, -2(t7)
-    lbu           t4, 0(t7)
-    addiu         t3, 1
-    addiu         t4, 2
-    addu          t3, t3, t2
-    addu          t4, t4, t2
-    srl           t3, 2
-    srl           t4, 2
-    sb            t3, 0(s2)
-    sb            t4, 1(s2)
-    addiu         t8, -1
-    bgtz          t8, 2b
-     addiu        s2, 2
-
-22:
-    lbu           t0, 0(t7)
-    lbu           t2, -1(t7)
-    sll           t1, t0, 1
-    addu          t1, t1, t0      // t1 = invalue * 3
-    addu          t1, t1, t2
-    addiu         t1, 1
-    srl           t1, t1, 2
-    sb            t1, 0(s2)
-    sb            t0, 1(s2)
-    addiu         s1, 4
-    bne           s1, s0, 0b
-     addiu        a2, 4
-3:
-    RESTORE_REGS_FROM_STACK 16, s0, s1, s2, s3
-
-    j             ra
-     nop
-END(jsimd_h2v1_fancy_upsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v1_downsample_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = cinfo->max_v_samp_factor
- * a2     = compptr->v_samp_factor
- * a3     = compptr->width_in_blocks
- * 16(sp) = input_data
- * 20(sp) = output_data
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 24, s0, s1, s2, s3, s4
-
-    beqz        a2, 7f
-     lw         s1, 44(sp)      // s1 = output_data
-    lw          s0, 40(sp)      // s0 = input_data
-    srl         s2, a0, 2
-    andi        t9, a0, 2
-    srl         t7, t9, 1
-    addu        s2, t7, s2
-    sll         t0, a3, 3       // t0 = width_in_blocks*DCT
-    srl         t7, t0, 1
-    subu        s2, t7, s2
-0:
-    andi        t6, a0, 1       // t6 = temp_index
-    addiu       t6, -1
-    lw          t4, 0(s1)       // t4 = outptr
-    lw          t5, 0(s0)       // t5 = inptr0
-    li          s3, 0           // s3 = bias
-    srl         t7, a0, 1       // t7 = image_width1
-    srl         s4, t7, 2
-    andi        t8, t7, 3
-1:
-    ulhu        t0, 0(t5)
-    ulhu        t1, 2(t5)
-    ulhu        t2, 4(t5)
-    ulhu        t3, 6(t5)
-    raddu.w.qb  t0, t0
-    raddu.w.qb  t1, t1
-    raddu.w.qb  t2, t2
-    raddu.w.qb  t3, t3
-    shra.ph     t0, t0, 1
-    shra_r.ph   t1, t1, 1
-    shra.ph     t2, t2, 1
-    shra_r.ph   t3, t3, 1
-    sb          t0, 0(t4)
-    sb          t1, 1(t4)
-    sb          t2, 2(t4)
-    sb          t3, 3(t4)
-    addiu       s4, -1
-    addiu       t4, 4
-    bgtz        s4, 1b
-     addiu      t5, 8
-    beqz        t8, 3f
-     addu       s4, t4, t8
-2:
-    ulhu        t0, 0(t5)
-    raddu.w.qb  t0, t0
-    addqh.w     t0, t0, s3
-    xori        s3, s3, 1
-    sb          t0, 0(t4)
-    addiu       t4, 1
-    bne         t4, s4, 2b
-     addiu      t5, 2
-3:
-    lbux        t1, t6(t5)
-    sll         t1, 1
-    addqh.w     t2, t1, s3      // t2 = pixval1
-    xori        s3, s3, 1
-    addqh.w     t3, t1, s3      // t3 = pixval2
-    blez        s2, 5f
-     append     t3, t2,  8
-    addu        t5, t4, s2      // t5 = loop_end2
-4:
-    ush         t3, 0(t4)
-    addiu       s2, -1
-    bgtz        s2, 4b
-     addiu      t4,  2
-5:
-    beqz        t9, 6f
-     nop
-    sb          t2, 0(t4)
-6:
-    addiu       s1, 4
-    addiu       a2, -1
-    bnez        a2, 0b
-     addiu      s0, 4
-7:
-    RESTORE_REGS_FROM_STACK 24, s0, s1, s2, s3, s4
-
-    j           ra
-    nop
-END(jsimd_h2v1_downsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v2_downsample_dspr2)
-/*
- * a0     = cinfo->image_width
- * a1     = cinfo->max_v_samp_factor
- * a2     = compptr->v_samp_factor
- * a3     = compptr->width_in_blocks
- * 16(sp) = input_data
- * 20(sp) = output_data
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    beqz        a2, 8f
-     lw         s1, 52(sp)      // s1 = output_data
-    lw          s0, 48(sp)      // s0 = input_data
-
-    andi        t6, a0, 1       // t6 = temp_index
-    addiu       t6, -1
-    srl         t7, a0, 1       // t7 = image_width1
-    srl         s4, t7, 2
-    andi        t8, t7, 3
-    andi        t9, a0, 2
-    srl         s2, a0, 2
-    srl         t7, t9, 1
-    addu        s2, t7, s2
-    sll         t0, a3, 3       // s2 = width_in_blocks*DCT
-    srl         t7, t0, 1
-    subu        s2, t7, s2
-0:
-    lw          t4, 0(s1)       // t4 = outptr
-    lw          t5, 0(s0)       // t5 = inptr0
-    lw          s7, 4(s0)       // s7 = inptr1
-    li          s6, 1           // s6 = bias
-2:
-    ulw         t0, 0(t5)       // t0 = |P3|P2|P1|P0|
-    ulw         t1, 0(s7)       // t1 = |Q3|Q2|Q1|Q0|
-    ulw         t2, 4(t5)
-    ulw         t3, 4(s7)
-    precrq.ph.w t7, t0, t1      // t2 = |P3|P2|Q3|Q2|
-    ins         t0, t1, 16, 16  // t0 = |Q1|Q0|P1|P0|
-    raddu.w.qb  t1, t7
-    raddu.w.qb  t0, t0
-    shra_r.w    t1, t1, 2
-    addiu       t0, 1
-    srl         t0, 2
-    precrq.ph.w t7, t2, t3
-    ins         t2, t3, 16, 16
-    raddu.w.qb  t7, t7
-    raddu.w.qb  t2, t2
-    shra_r.w    t7, t7, 2
-    addiu       t2, 1
-    srl         t2, 2
-    sb          t0, 0(t4)
-    sb          t1, 1(t4)
-    sb          t2, 2(t4)
-    sb          t7, 3(t4)
-    addiu       t4, 4
-    addiu       t5, 8
-    addiu       s4, s4, -1
-    bgtz        s4, 2b
-     addiu      s7, 8
-    beqz        t8, 4f
-     addu       t8, t4, t8
-3:
-    ulhu        t0, 0(t5)
-    ulhu        t1, 0(s7)
-    ins         t0, t1, 16, 16
-    raddu.w.qb  t0, t0
-    addu        t0, t0, s6
-    srl         t0, 2
-    xori        s6, s6, 3
-    sb          t0, 0(t4)
-    addiu       t5, 2
-    addiu       t4, 1
-    bne         t8, t4, 3b
-     addiu      s7, 2
-4:
-    lbux        t1, t6(t5)
-    sll         t1, 1
-    lbux        t0, t6(s7)
-    sll         t0, 1
-    addu        t1, t1, t0
-    addu        t3, t1, s6
-    srl         t0, t3, 2       // t2 = pixval1
-    xori        s6, s6, 3
-    addu        t2, t1, s6
-    srl         t1, t2, 2       // t3 = pixval2
-    blez        s2, 6f
-     append     t1, t0, 8
-5:
-    ush         t1, 0(t4)
-    addiu       s2, -1
-    bgtz        s2, 5b
-     addiu      t4, 2
-6:
-    beqz        t9, 7f
-     nop
-    sb          t0, 0(t4)
-7:
-    addiu       s1, 4
-    addiu       a2, -1
-    bnez        a2, 0b
-     addiu      s0, 8
-8:
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-END(jsimd_h2v2_downsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v2_smooth_downsample_dspr2)
-/*
- * a0     = input_data
- * a1     = output_data
- * a2     = compptr->v_samp_factor
- * a3     = cinfo->max_v_samp_factor
- * 16(sp) = cinfo->smoothing_factor
- * 20(sp) = compptr->width_in_blocks
- * 24(sp) = cinfo->image_width
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    lw          s7, 52(sp)      // compptr->width_in_blocks
-    lw          s0, 56(sp)      // cinfo->image_width
-    lw          s6, 48(sp)      // cinfo->smoothing_factor
-    sll         s7, 3           // output_cols = width_in_blocks * DCTSIZE
-    sll         v0, s7, 1
-    subu        v0, v0, s0
-    blez        v0, 2f
-    move        v1, zero
-    addiu       t0, a3, 2       // t0 = cinfo->max_v_samp_factor + 2
-0:
-    addiu       t1, a0, -4
-    sll         t2, v1, 2
-    lwx         t1, t2(t1)
-    move        t3, v0
-    addu        t1, t1, s0
-    lbu         t2, -1(t1)
-1:
-    addiu       t3, t3, -1
-    sb          t2, 0(t1)
-    bgtz        t3, 1b
-    addiu       t1, t1, 1
-    addiu       v1, v1, 1
-    bne         v1, t0, 0b
-    nop
-2:
-    li          v0, 80
-    mul         v0, s6, v0
-    li          v1, 16384
-    move        t4, zero
-    move        t5, zero
-    subu        t6, v1, v0      // t6 = 16384 - tmp_smoot_f * 80
-    sll         t7, s6, 4       // t7 = tmp_smoot_f * 16
-3:
-/* Special case for first column: pretend column -1 is same as column 0 */
-    sll         v0, t4, 2
-    lwx         t8, v0(a1)      //  outptr = output_data[outrow]
-    sll         v1, t5, 2
-    addiu       t9, v1, 4
-    addiu       s0, v1, -4
-    addiu       s1, v1, 8
-    lwx         s2, v1(a0)      // inptr0 = input_data[inrow]
-    lwx         t9, t9(a0)      // inptr1 = input_data[inrow+1]
-    lwx         s0, s0(a0)      // above_ptr = input_data[inrow-1]
-    lwx         s1, s1(a0)      // below_ptr = input_data[inrow+2]
-    lh          v0, 0(s2)
-    lh          v1, 0(t9)
-    lh          t0, 0(s0)
-    lh          t1, 0(s1)
-    ins         v0, v1, 16, 16
-    ins         t0, t1, 16, 16
-    raddu.w.qb  t2, v0
-    raddu.w.qb  s3, t0
-    lbu         v0, 0(s2)
-    lbu         v1, 2(s2)
-    lbu         t0, 0(t9)
-    lbu         t1, 2(t9)
-    addu        v0, v0, v1
-    mult        $ac1, t2, t6
-    addu        t0, t0, t1
-    lbu         t2, 2(s0)
-    addu        t0, t0, v0
-    lbu         t3, 2(s1)
-    addu        s3, t0, s3
-    lbu         v0, 0(s0)
-    lbu         t0, 0(s1)
-    sll         s3, s3, 1
-    addu        v0, v0, t2
-    addu        t0, t0, t3
-    addu        t0, t0, v0
-    addu        s3, t0, s3
-    madd        $ac1, s3, t7
-    extr_r.w    v0, $ac1, 16
-    addiu       t8, t8, 1
-    addiu       s2, s2, 2
-    addiu       t9, t9, 2
-    addiu       s0, s0, 2
-    addiu       s1, s1, 2
-    sb          v0, -1(t8)
-    addiu       s4, s7, -2
-    and         s4, s4, 3
-    addu        s5, s4, t8      // end address
-4:
-    lh          v0, 0(s2)
-    lh          v1, 0(t9)
-    lh          t0, 0(s0)
-    lh          t1, 0(s1)
-    ins         v0, v1, 16, 16
-    ins         t0, t1, 16, 16
-    raddu.w.qb  t2, v0
-    raddu.w.qb  s3, t0
-    lbu         v0, -1(s2)
-    lbu         v1, 2(s2)
-    lbu         t0, -1(t9)
-    lbu         t1, 2(t9)
-    addu        v0, v0, v1
-    mult        $ac1, t2, t6
-    addu        t0, t0, t1
-    lbu         t2, 2(s0)
-    addu        t0, t0, v0
-    lbu         t3, 2(s1)
-    addu        s3, t0, s3
-    lbu         v0, -1(s0)
-    lbu         t0, -1(s1)
-    sll         s3, s3, 1
-    addu        v0, v0, t2
-    addu        t0, t0, t3
-    addu        t0, t0, v0
-    addu        s3, t0, s3
-    madd        $ac1, s3, t7
-    extr_r.w    t2, $ac1, 16
-    addiu       t8, t8, 1
-    addiu       s2, s2, 2
-    addiu       t9, t9, 2
-    addiu       s0, s0, 2
-    sb          t2, -1(t8)
-    bne         s5, t8, 4b
-    addiu       s1, s1, 2
-    addiu       s5, s7, -2
-    subu        s5, s5, s4
-    addu        s5, s5, t8      // end address
-5:
-    lh          v0, 0(s2)
-    lh          v1, 0(t9)
-    lh          t0, 0(s0)
-    lh          t1, 0(s1)
-    ins         v0, v1, 16, 16
-    ins         t0, t1, 16, 16
-    raddu.w.qb  t2, v0
-    raddu.w.qb  s3, t0
-    lbu         v0, -1(s2)
-    lbu         v1, 2(s2)
-    lbu         t0, -1(t9)
-    lbu         t1, 2(t9)
-    addu        v0, v0, v1
-    mult        $ac1, t2, t6
-    addu        t0, t0, t1
-    lbu         t2, 2(s0)
-    addu        t0, t0, v0
-    lbu         t3, 2(s1)
-    addu        s3, t0, s3
-    lbu         v0, -1(s0)
-    lbu         t0, -1(s1)
-    sll         s3, s3, 1
-    addu        v0, v0, t2
-    addu        t0, t0, t3
-    lh          v1, 2(t9)
-    addu        t0, t0, v0
-    lh          v0, 2(s2)
-    addu        s3, t0, s3
-    lh          t0, 2(s0)
-    lh          t1, 2(s1)
-    madd        $ac1, s3, t7
-    extr_r.w    t2, $ac1, 16
-    ins         t0, t1, 16, 16
-    ins         v0, v1, 16, 16
-    raddu.w.qb  s3, t0
-    lbu         v1, 4(s2)
-    lbu         t0, 1(t9)
-    lbu         t1, 4(t9)
-    sb          t2, 0(t8)
-    raddu.w.qb  t3, v0
-    lbu         v0, 1(s2)
-    addu        t0, t0, t1
-    mult        $ac1, t3, t6
-    addu        v0, v0, v1
-    lbu         t2, 4(s0)
-    addu        t0, t0, v0
-    lbu         v0, 1(s0)
-    addu        s3, t0, s3
-    lbu         t0, 1(s1)
-    lbu         t3, 4(s1)
-    addu        v0, v0, t2
-    sll         s3, s3, 1
-    addu        t0, t0, t3
-    lh          v1, 4(t9)
-    addu        t0, t0, v0
-    lh          v0, 4(s2)
-    addu        s3, t0, s3
-    lh          t0, 4(s0)
-    lh          t1, 4(s1)
-    madd        $ac1, s3, t7
-    extr_r.w    t2, $ac1, 16
-    ins         t0, t1, 16, 16
-    ins         v0, v1, 16, 16
-    raddu.w.qb  s3, t0
-    lbu         v1, 6(s2)
-    lbu         t0, 3(t9)
-    lbu         t1, 6(t9)
-    sb          t2, 1(t8)
-    raddu.w.qb  t3, v0
-    lbu         v0, 3(s2)
-    addu        t0, t0, t1
-    mult        $ac1, t3, t6
-    addu        v0, v0, v1
-    lbu         t2, 6(s0)
-    addu        t0, t0, v0
-    lbu         v0, 3(s0)
-    addu        s3, t0, s3
-    lbu         t0, 3(s1)
-    lbu         t3, 6(s1)
-    addu        v0, v0, t2
-    sll         s3, s3, 1
-    addu        t0, t0, t3
-    lh          v1, 6(t9)
-    addu        t0, t0, v0
-    lh          v0, 6(s2)
-    addu        s3, t0, s3
-    lh          t0, 6(s0)
-    lh          t1, 6(s1)
-    madd        $ac1, s3, t7
-    extr_r.w    t3, $ac1, 16
-    ins         t0, t1, 16, 16
-    ins         v0, v1, 16, 16
-    raddu.w.qb  s3, t0
-    lbu         v1, 8(s2)
-    lbu         t0, 5(t9)
-    lbu         t1, 8(t9)
-    sb          t3, 2(t8)
-    raddu.w.qb  t2, v0
-    lbu         v0, 5(s2)
-    addu        t0, t0, t1
-    mult        $ac1, t2, t6
-    addu        v0, v0, v1
-    lbu         t2, 8(s0)
-    addu        t0, t0, v0
-    lbu         v0, 5(s0)
-    addu        s3, t0, s3
-    lbu         t0, 5(s1)
-    lbu         t3, 8(s1)
-    addu        v0, v0, t2
-    sll         s3, s3, 1
-    addu        t0, t0, t3
-    addiu       t8, t8, 4
-    addu        t0, t0, v0
-    addiu       s2, s2, 8
-    addu        s3, t0, s3
-    addiu       t9, t9, 8
-    madd        $ac1, s3, t7
-    extr_r.w    t1, $ac1, 16
-    addiu       s0, s0, 8
-    addiu       s1, s1, 8
-    bne         s5, t8, 5b
-    sb          t1, -1(t8)
-/* Special case for last column */
-    lh          v0, 0(s2)
-    lh          v1, 0(t9)
-    lh          t0, 0(s0)
-    lh          t1, 0(s1)
-    ins         v0, v1, 16, 16
-    ins         t0, t1, 16, 16
-    raddu.w.qb  t2, v0
-    raddu.w.qb  s3, t0
-    lbu         v0, -1(s2)
-    lbu         v1, 1(s2)
-    lbu         t0, -1(t9)
-    lbu         t1, 1(t9)
-    addu        v0, v0, v1
-    mult        $ac1, t2, t6
-    addu        t0, t0, t1
-    lbu         t2, 1(s0)
-    addu        t0, t0, v0
-    lbu         t3, 1(s1)
-    addu        s3, t0, s3
-    lbu         v0, -1(s0)
-    lbu         t0, -1(s1)
-    sll         s3, s3, 1
-    addu        v0, v0, t2
-    addu        t0, t0, t3
-    addu        t0, t0, v0
-    addu        s3, t0, s3
-    madd        $ac1, s3, t7
-    extr_r.w    t0, $ac1, 16
-    addiu       t5, t5, 2
-    sb          t0, 0(t8)
-    addiu       t4, t4, 1
-    bne         t4, a2, 3b
-    addiu       t5, t5, 2
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-
-END(jsimd_h2v2_smooth_downsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_int_upsample_dspr2)
-/*
- * a0     = upsample->h_expand[compptr->component_index]
- * a1     = upsample->v_expand[compptr->component_index]
- * a2     = input_data
- * a3     = output_data_ptr
- * 16(sp) = cinfo->output_width
- * 20(sp) = cinfo->max_v_samp_factor
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 16, s0, s1, s2, s3
-
-    lw          s0, 0(a3)       // s0 = output_data
-    lw          s1, 32(sp)      // s1 = cinfo->output_width
-    lw          s2, 36(sp)      // s2 = cinfo->max_v_samp_factor
-    li          t6, 0           // t6 = inrow
-    beqz        s2, 10f
-     li         s3, 0           // s3 = outrow
-0:
-    addu        t0, a2, t6
-    addu        t7, s0, s3
-    lw          t3, 0(t0)       // t3 = inptr
-    lw          t8, 0(t7)       // t8 = outptr
-    beqz        s1, 4f
-     addu       t5, t8, s1      // t5 = outend
-1:
-    lb          t2, 0(t3)       // t2 = invalue = *inptr++
-    addiu       t3, 1
-    beqz        a0, 3f
-     move       t0, a0          // t0 = h_expand
-2:
-    sb          t2, 0(t8)
-    addiu       t0, -1
-    bgtz        t0, 2b
-     addiu      t8, 1
-3:
-    bgt         t5, t8, 1b
-     nop
-4:
-    addiu       t9, a1, -1      // t9 = v_expand - 1
-    blez        t9, 9f
-     nop
-5:
-    lw          t3, 0(s0)
-    lw          t4, 4(s0)
-    subu        t0, s1, 0xF
-    blez        t0, 7f
-     addu       t5, t3, s1      // t5 = end address
-    andi        t7, s1, 0xF     // t7 = residual
-    subu        t8, t5, t7
-6:
-    ulw         t0, 0(t3)
-    ulw         t1, 4(t3)
-    ulw         t2, 8(t3)
-    usw         t0, 0(t4)
-    ulw         t0, 12(t3)
-    usw         t1, 4(t4)
-    usw         t2, 8(t4)
-    usw         t0, 12(t4)
-    addiu       t3, 16
-    bne         t3, t8, 6b
-     addiu      t4, 16
-    beqz        t7, 8f
-     nop
-7:
-    lbu         t0, 0(t3)
-    sb          t0, 0(t4)
-    addiu       t3, 1
-    bne         t3, t5, 7b
-     addiu      t4, 1
-8:
-    addiu       t9, -1
-    bgtz        t9, 5b
-     addiu      s0, 8
-9:
-    addu        s3, s3, a1
-    bne         s3, s2, 0b
-     addiu      t6, 1
-10:
-    RESTORE_REGS_FROM_STACK 16, s0, s1, s2, s3
-
-    j           ra
-     nop
-END(jsimd_int_upsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v1_upsample_dspr2)
-/*
- * a0 = cinfo->max_v_samp_factor
- * a1 = cinfo->output_width
- * a2 = input_data
- * a3 = output_data_ptr
- */
-    lw          t7, 0(a3)       // t7 = output_data
-    andi        t8, a1, 0xf     // t8 = residual
-    sll         t0, a0, 2
-    blez        a0, 4f
-     addu       t9, t7, t0      // t9 = output_data end address
-0:
-    lw          t5, 0(t7)       // t5 = outptr
-    lw          t6, 0(a2)       // t6 = inptr
-    addu        t3, t5, a1      // t3 = outptr + output_width (end address)
-    subu        t3, t8          // t3 = end address - residual
-    beq         t5, t3, 2f
-     move       t4, t8
-1:
-    ulw         t0, 0(t6)       // t0 = |P3|P2|P1|P0|
-    ulw         t2, 4(t6)       // t2 = |P7|P6|P5|P4|
-    srl         t1, t0, 16      // t1 = |X|X|P3|P2|
-    ins         t0, t0, 16, 16  // t0 = |P1|P0|P1|P0|
-    ins         t1, t1, 16, 16  // t1 = |P3|P2|P3|P2|
-    ins         t0, t0, 8, 16   // t0 = |P1|P1|P0|P0|
-    ins         t1, t1, 8, 16   // t1 = |P3|P3|P2|P2|
-    usw         t0, 0(t5)
-    usw         t1, 4(t5)
-    srl         t0, t2, 16      // t0 = |X|X|P7|P6|
-    ins         t2, t2, 16, 16  // t2 = |P5|P4|P5|P4|
-    ins         t0, t0, 16, 16  // t0 = |P7|P6|P7|P6|
-    ins         t2, t2, 8, 16   // t2 = |P5|P5|P4|P4|
-    ins         t0, t0, 8, 16   // t0 = |P7|P7|P6|P6|
-    usw         t2, 8(t5)
-    usw         t0, 12(t5)
-    addiu       t5, 16
-    bne         t5, t3, 1b
-     addiu      t6, 8
-    beqz        t8, 3f
-     move       t4, t8
-2:
-    lbu         t1, 0(t6)
-    sb          t1, 0(t5)
-    sb          t1, 1(t5)
-    addiu       t4, -2
-    addiu       t6, 1
-    bgtz        t4, 2b
-     addiu      t5, 2
-3:
-    addiu       t7, 4
-    bne         t9, t7, 0b
-     addiu      a2, 4
-4:
-    j           ra
-     nop
-END(jsimd_h2v1_upsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_h2v2_upsample_dspr2)
-/*
- * a0 = cinfo->max_v_samp_factor
- * a1 = cinfo->output_width
- * a2 = input_data
- * a3 = output_data_ptr
- */
-    lw          t7, 0(a3)
-    blez        a0, 7f
-     andi       t9, a1, 0xf     // t9 = residual
-0:
-    lw          t6, 0(a2)       // t6 = inptr
-    lw          t5, 0(t7)       // t5 = outptr
-    addu        t8, t5, a1      // t8 = outptr end address
-    subu        t8, t9          // t8 = end address - residual
-    beq         t5, t8, 2f
-     move       t4, t9
-1:
-    ulw         t0, 0(t6)
-    srl         t1, t0, 16
-    ins         t0, t0, 16, 16
-    ins         t0, t0, 8, 16
-    ins         t1, t1, 16, 16
-    ins         t1, t1, 8, 16
-    ulw         t2, 4(t6)
-    usw         t0, 0(t5)
-    usw         t1, 4(t5)
-    srl         t3, t2, 16
-    ins         t2, t2, 16, 16
-    ins         t2, t2, 8, 16
-    ins         t3, t3, 16, 16
-    ins         t3, t3, 8, 16
-    usw         t2, 8(t5)
-    usw         t3, 12(t5)
-    addiu       t5, 16
-    bne         t5, t8, 1b
-     addiu      t6, 8
-    beqz        t9, 3f
-     move       t4, t9
-2:
-    lbu         t0, 0(t6)
-    sb          t0, 0(t5)
-    sb          t0, 1(t5)
-    addiu       t4, -2
-    addiu       t6, 1
-    bgtz        t4, 2b
-     addiu      t5, 2
-3:
-    lw          t6, 0(t7)       // t6 = outptr[0]
-    lw          t5, 4(t7)       // t5 = outptr[1]
-    addu        t4, t6, a1      // t4 = new end address
-    beq         a1, t9, 5f
-     subu       t8, t4, t9
-4:
-    ulw         t0, 0(t6)
-    ulw         t1, 4(t6)
-    ulw         t2, 8(t6)
-    usw         t0, 0(t5)
-    ulw         t0, 12(t6)
-    usw         t1, 4(t5)
-    usw         t2, 8(t5)
-    usw         t0, 12(t5)
-    addiu       t6, 16
-    bne         t6, t8, 4b
-     addiu      t5, 16
-    beqz        t9, 6f
-     nop
-5:
-    lbu         t0, 0(t6)
-    sb          t0, 0(t5)
-    addiu       t6, 1
-    bne         t6, t4, 5b
-     addiu      t5, 1
-6:
-    addiu       t7, 8
-    addiu       a0, -2
-    bgtz        a0, 0b
-     addiu      a2, 4
-7:
-    j           ra
-     nop
-END(jsimd_h2v2_upsample_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_islow_dspr2)
-/*
- * a0 = coef_block
- * a1 = compptr->dcttable
- * a2 = output
- * a3 = range_limit
- */
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    addiu       sp, sp, -256
-    move        v0, sp
-    addiu       v1, zero, 8     // v1 = DCTSIZE = 8
-1:
-    lh          s4, 32(a0)      // s4 = inptr[16]
-    lh          s5, 64(a0)      // s5 = inptr[32]
-    lh          s6, 96(a0)      // s6 = inptr[48]
-    lh          t1, 112(a0)     // t1 = inptr[56]
-    lh          t7, 16(a0)      // t7 = inptr[8]
-    lh          t5, 80(a0)      // t5 = inptr[40]
-    lh          t3, 48(a0)      // t3 = inptr[24]
-    or          s4, s4, t1
-    or          s4, s4, t3
-    or          s4, s4, t5
-    or          s4, s4, t7
-    or          s4, s4, s5
-    or          s4, s4, s6
-    bnez        s4, 2f
-     addiu      v1, v1, -1
-    lh          s5, 0(a1)       // quantptr[DCTSIZE*0]
-    lh          s6, 0(a0)       // inptr[DCTSIZE*0]
-    mul         s5, s5, s6      // DEQUANTIZE(inptr[0], quantptr[0])
-    sll         s5, s5, 2
-    sw          s5, 0(v0)
-    sw          s5, 32(v0)
-    sw          s5, 64(v0)
-    sw          s5, 96(v0)
-    sw          s5, 128(v0)
-    sw          s5, 160(v0)
-    sw          s5, 192(v0)
-    b           3f
-     sw         s5, 224(v0)
-2:
-    lh          t0, 112(a1)
-    lh          t2, 48(a1)
-    lh          t4, 80(a1)
-    lh          t6, 16(a1)
-    mul         t0, t0, t1      // DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7])
-    mul         t1, t2, t3      // DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3])
-    mul         t2, t4, t5      // DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5])
-    mul         t3, t6, t7      // DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1])
-    lh          t4, 32(a1)
-    lh          t5, 32(a0)
-    lh          t6, 96(a1)
-    lh          t7, 96(a0)
-    addu        s0, t0, t1       // z3 = tmp0 + tmp2
-    addu        s1, t1, t2       // z2 = tmp1 + tmp2
-    addu        s2, t2, t3       // z4 = tmp1 + tmp3
-    addu        s3, s0, s2       // z3 + z4
-    addiu       t9, zero, 9633   // FIX_1_175875602
-    mul         s3, s3, t9       // z5 = MULTIPLY(z3 + z4, FIX_1_175875602)
-    addu        t8, t0, t3       // z1 = tmp0 + tmp3
-    addiu       t9, zero, 2446   // FIX_0_298631336
-    mul         t0, t0, t9       // tmp0 = MULTIPLY(tmp0, FIX_0_298631336)
-    addiu       t9, zero, 16819  // FIX_2_053119869
-    mul         t2, t2, t9       // tmp1 = MULTIPLY(tmp1, FIX_2_053119869)
-    addiu       t9, zero, 25172  // FIX_3_072711026
-    mul         t1, t1, t9       // tmp2 = MULTIPLY(tmp2, FIX_3_072711026)
-    addiu       t9, zero, 12299  // FIX_1_501321110
-    mul         t3, t3, t9       // tmp3 = MULTIPLY(tmp3, FIX_1_501321110)
-    addiu       t9, zero, 16069  // FIX_1_961570560
-    mul         s0, s0, t9       // -z3 = MULTIPLY(z3, FIX_1_961570560)
-    addiu       t9, zero, 3196   // FIX_0_390180644
-    mul         s2, s2, t9       // -z4 = MULTIPLY(z4, FIX_0_390180644)
-    addiu       t9, zero, 7373   // FIX_0_899976223
-    mul         t8, t8, t9       // -z1 = MULTIPLY(z1, FIX_0_899976223)
-    addiu       t9, zero, 20995  // FIX_2_562915447
-    mul         s1, s1, t9       // -z2 = MULTIPLY(z2, FIX_2_562915447)
-    subu        s0, s3, s0       // z3 += z5
-    addu        t0, t0, s0       // tmp0 += z3
-    addu        t1, t1, s0       // tmp2 += z3
-    subu        s2, s3, s2       // z4 += z5
-    addu        t2, t2, s2       // tmp1 += z4
-    addu        t3, t3, s2       // tmp3 += z4
-    subu        t0, t0, t8       // tmp0 += z1
-    subu        t1, t1, s1       // tmp2 += z2
-    subu        t2, t2, s1       // tmp1 += z2
-    subu        t3, t3, t8       // tmp3 += z1
-    mul         s0, t4, t5       // DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2])
-    addiu       t9, zero, 6270   // FIX_0_765366865
-    mul         s1, t6, t7       // DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6])
-    lh          t4, 0(a1)
-    lh          t5, 0(a0)
-    lh          t6, 64(a1)
-    lh          t7, 64(a0)
-    mul         s2, t9, s0       // MULTIPLY(z2, FIX_0_765366865)
-    mul         t5, t4, t5       // DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0])
-    mul         t6, t6, t7       // DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4])
-    addiu       t9, zero, 4433   // FIX_0_541196100
-    addu        s3, s0, s1       // z2 + z3
-    mul         s3, s3, t9       // z1 = MULTIPLY(z2 + z3, FIX_0_541196100)
-    addiu       t9, zero, 15137  // FIX_1_847759065
-    mul         t8, s1, t9       // MULTIPLY(z3, FIX_1_847759065)
-    addu        t4, t5, t6
-    subu        t5, t5, t6
-    sll         t4, t4, 13      // tmp0 = (z2 + z3) << CONST_BITS
-    sll         t5, t5, 13      // tmp1 = (z2 - z3) << CONST_BITS
-    addu        t7, s3, s2      // tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865)
-    subu        t6, s3, t8      // tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065)
-    addu        s0, t4, t7
-    subu        s1, t4, t7
-    addu        s2, t5, t6
-    subu        s3, t5, t6
-    addu        t4, s0, t3
-    subu        s0, s0, t3
-    addu        t3, s2, t1
-    subu        s2, s2, t1
-    addu        t1, s3, t2
-    subu        s3, s3, t2
-    addu        t2, s1, t0
-    subu        s1, s1, t0
-    shra_r.w    t4, t4, 11
-    shra_r.w    t3, t3, 11
-    shra_r.w    t1, t1, 11
-    shra_r.w    t2, t2, 11
-    shra_r.w    s1, s1, 11
-    shra_r.w    s3, s3, 11
-    shra_r.w    s2, s2, 11
-    shra_r.w    s0, s0, 11
-    sw          t4, 0(v0)
-    sw          t3, 32(v0)
-    sw          t1, 64(v0)
-    sw          t2, 96(v0)
-    sw          s1, 128(v0)
-    sw          s3, 160(v0)
-    sw          s2, 192(v0)
-    sw          s0, 224(v0)
-3:
-    addiu       a1, a1, 2
-    addiu       a0, a0, 2
-    bgtz        v1, 1b
-     addiu      v0, v0, 4
-    move        v0, sp
-    addiu       v1, zero, 8
-4:
-    lw          t0, 8(v0)       // z2 = (JLONG)wsptr[2]
-    lw          t1, 24(v0)      // z3 = (JLONG)wsptr[6]
-    lw          t2, 0(v0)       // (JLONG)wsptr[0]
-    lw          t3, 16(v0)      // (JLONG)wsptr[4]
-    lw          s4, 4(v0)       // (JLONG)wsptr[1]
-    lw          s5, 12(v0)      // (JLONG)wsptr[3]
-    lw          s6, 20(v0)      // (JLONG)wsptr[5]
-    lw          s7, 28(v0)      // (JLONG)wsptr[7]
-    or          s4, s4, t0
-    or          s4, s4, t1
-    or          s4, s4, t3
-    or          s4, s4, s7
-    or          s4, s4, s5
-    or          s4, s4, s6
-    bnez        s4, 5f
-     addiu      v1, v1, -1
-    shra_r.w    s5, t2, 5
-    andi        s5, s5, 0x3ff
-    lbux        s5, s5(a3)
-    lw          s1, 0(a2)
-    replv.qb    s5, s5
-    usw         s5, 0(s1)
-    usw         s5, 4(s1)
-    b           6f
-     nop
-5:
-    addu        t4, t0, t1       // z2 + z3
-    addiu       t8, zero, 4433   // FIX_0_541196100
-    mul         t5, t4, t8       // z1 = MULTIPLY(z2 + z3, FIX_0_541196100)
-    addiu       t8, zero, 15137  // FIX_1_847759065
-    mul         t1, t1, t8       // MULTIPLY(z3, FIX_1_847759065)
-    addiu       t8, zero, 6270   // FIX_0_765366865
-    mul         t0, t0, t8       // MULTIPLY(z2, FIX_0_765366865)
-    addu        t4, t2, t3       // (JLONG)wsptr[0] + (JLONG)wsptr[4]
-    subu        t2, t2, t3       // (JLONG)wsptr[0] - (JLONG)wsptr[4]
-    sll         t4, t4, 13       // tmp0 = (wsptr[0] + wsptr[4]) << CONST_BITS
-    sll         t2, t2, 13       // tmp1 = (wsptr[0] - wsptr[4]) << CONST_BITS
-    subu        t1, t5, t1       // tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065)
-    subu        t3, t2, t1       // tmp12 = tmp1 - tmp2
-    addu        t2, t2, t1       // tmp11 = tmp1 + tmp2
-    addu        t5, t5, t0       // tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865)
-    subu        t1, t4, t5       // tmp13 = tmp0 - tmp3
-    addu        t0, t4, t5       // tmp10 = tmp0 + tmp3
-    lw          t4, 28(v0)       // tmp0 = (JLONG)wsptr[7]
-    lw          t6, 12(v0)       // tmp2 = (JLONG)wsptr[3]
-    lw          t5, 20(v0)       // tmp1 = (JLONG)wsptr[5]
-    lw          t7, 4(v0)        // tmp3 = (JLONG)wsptr[1]
-    addu        s0, t4, t6       // z3 = tmp0 + tmp2
-    addiu       t8, zero, 9633   // FIX_1_175875602
-    addu        s1, t5, t7       // z4 = tmp1 + tmp3
-    addu        s2, s0, s1       // z3 + z4
-    mul         s2, s2, t8       // z5 = MULTIPLY(z3 + z4, FIX_1_175875602)
-    addu        s3, t4, t7       // z1 = tmp0 + tmp3
-    addu        t9, t5, t6       // z2 = tmp1 + tmp2
-    addiu       t8, zero, 16069  // FIX_1_961570560
-    mul         s0, s0, t8       // -z3 = MULTIPLY(z3, FIX_1_961570560)
-    addiu       t8, zero, 3196   // FIX_0_390180644
-    mul         s1, s1, t8       // -z4 = MULTIPLY(z4, FIX_0_390180644)
-    addiu       t8, zero, 2446   // FIX_0_298631336
-    mul         t4, t4, t8       // tmp0 = MULTIPLY(tmp0, FIX_0_298631336)
-    addiu       t8, zero, 7373   // FIX_0_899976223
-    mul         s3, s3, t8       // -z1 = MULTIPLY(z1, FIX_0_899976223)
-    addiu       t8, zero, 16819  // FIX_2_053119869
-    mul         t5, t5, t8       // tmp1 = MULTIPLY(tmp1, FIX_2_053119869)
-    addiu       t8, zero, 20995  // FIX_2_562915447
-    mul         t9, t9, t8       // -z2 = MULTIPLY(z2, FIX_2_562915447)
-    addiu       t8, zero, 25172  // FIX_3_072711026
-    mul         t6, t6, t8       // tmp2 = MULTIPLY(tmp2, FIX_3_072711026)
-    addiu       t8, zero, 12299  // FIX_1_501321110
-    mul         t7, t7, t8       // tmp3 = MULTIPLY(tmp3, FIX_1_501321110)
-    subu        s0, s2, s0       // z3 += z5
-    subu        s1, s2, s1       // z4 += z5
-    addu        t4, t4, s0
-    subu        t4, t4, s3      // tmp0
-    addu        t5, t5, s1
-    subu        t5, t5, t9      // tmp1
-    addu        t6, t6, s0
-    subu        t6, t6, t9      // tmp2
-    addu        t7, t7, s1
-    subu        t7, t7, s3      // tmp3
-    addu        s0, t0, t7
-    subu        t0, t0, t7
-    addu        t7, t2, t6
-    subu        t2, t2, t6
-    addu        t6, t3, t5
-    subu        t3, t3, t5
-    addu        t5, t1, t4
-    subu        t1, t1, t4
-    shra_r.w    s0, s0, 18
-    shra_r.w    t7, t7, 18
-    shra_r.w    t6, t6, 18
-    shra_r.w    t5, t5, 18
-    shra_r.w    t1, t1, 18
-    shra_r.w    t3, t3, 18
-    shra_r.w    t2, t2, 18
-    shra_r.w    t0, t0, 18
-    andi        s0, s0, 0x3ff
-    andi        t7, t7, 0x3ff
-    andi        t6, t6, 0x3ff
-    andi        t5, t5, 0x3ff
-    andi        t1, t1, 0x3ff
-    andi        t3, t3, 0x3ff
-    andi        t2, t2, 0x3ff
-    andi        t0, t0, 0x3ff
-    lw          s1, 0(a2)
-    lbux        s0, s0(a3)
-    lbux        t7, t7(a3)
-    lbux        t6, t6(a3)
-    lbux        t5, t5(a3)
-    lbux        t1, t1(a3)
-    lbux        t3, t3(a3)
-    lbux        t2, t2(a3)
-    lbux        t0, t0(a3)
-    sb          s0, 0(s1)
-    sb          t7, 1(s1)
-    sb          t6, 2(s1)
-    sb          t5, 3(s1)
-    sb          t1, 4(s1)
-    sb          t3, 5(s1)
-    sb          t2, 6(s1)
-    sb          t0, 7(s1)
-6:
-    addiu       v0, v0, 32
-    bgtz        v1, 4b
-     addiu      a2, a2, 4
-    addiu       sp, sp, 256
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-
-END(jsimd_idct_islow_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_ifast_cols_dspr2)
-/*
- * a0 = inptr
- * a1 = quantptr
- * a2 = wsptr
- * a3 = mips_idct_ifast_coefs
- */
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    addiu         t9, a0, 16      // end address
-    or            AT, a3, zero
-
-0:
-    lw            s0, 0(a1)       // quantptr[DCTSIZE*0]
-    lw            t0, 0(a0)       // inptr[DCTSIZE*0]
-    lw            t1, 16(a0)      // inptr[DCTSIZE*1]
-    muleq_s.w.phl v0, t0, s0      // tmp0 ...
-    lw            t2, 32(a0)      // inptr[DCTSIZE*2]
-    lw            t3, 48(a0)      // inptr[DCTSIZE*3]
-    lw            t4, 64(a0)      // inptr[DCTSIZE*4]
-    lw            t5, 80(a0)      // inptr[DCTSIZE*5]
-    muleq_s.w.phr t0, t0, s0      // ... tmp0 ...
-    lw            t6, 96(a0)      // inptr[DCTSIZE*6]
-    lw            t7, 112(a0)     // inptr[DCTSIZE*7]
-    or            s4, t1, t2
-    or            s5, t3, t4
-    bnez          s4, 1f
-     ins          t0, v0, 16, 16  // ... tmp0
-    bnez          s5, 1f
-     or           s6, t5, t6
-    or            s6, s6, t7
-    bnez          s6, 1f
-     sw           t0, 0(a2)       // wsptr[DCTSIZE*0]
-    sw            t0, 16(a2)      // wsptr[DCTSIZE*1]
-    sw            t0, 32(a2)      // wsptr[DCTSIZE*2]
-    sw            t0, 48(a2)      // wsptr[DCTSIZE*3]
-    sw            t0, 64(a2)      // wsptr[DCTSIZE*4]
-    sw            t0, 80(a2)      // wsptr[DCTSIZE*5]
-    sw            t0, 96(a2)      // wsptr[DCTSIZE*6]
-    sw            t0, 112(a2)     // wsptr[DCTSIZE*7]
-    addiu         a0, a0, 4
-    b             2f
-     addiu        a1, a1, 4
-
-1:
-    lw            s1, 32(a1)      // quantptr[DCTSIZE*2]
-    lw            s2, 64(a1)      // quantptr[DCTSIZE*4]
-    muleq_s.w.phl v0, t2, s1      // tmp1 ...
-    muleq_s.w.phr t2, t2, s1      // ... tmp1 ...
-    lw            s0, 16(a1)      // quantptr[DCTSIZE*1]
-    lw            s1, 48(a1)      // quantptr[DCTSIZE*3]
-    lw            s3, 96(a1)      // quantptr[DCTSIZE*6]
-    muleq_s.w.phl v1, t4, s2      // tmp2 ...
-    muleq_s.w.phr t4, t4, s2      // ... tmp2 ...
-    lw            s2, 80(a1)      // quantptr[DCTSIZE*5]
-    lw            t8, 4(AT)       // FIX(1.414213562)
-    ins           t2, v0, 16, 16  // ... tmp1
-    muleq_s.w.phl v0, t6, s3      // tmp3 ...
-    muleq_s.w.phr t6, t6, s3      // ... tmp3 ...
-    ins           t4, v1, 16, 16  // ... tmp2
-    addq.ph       s4, t0, t4      // tmp10
-    subq.ph       s5, t0, t4      // tmp11
-    ins           t6, v0, 16, 16  // ... tmp3
-    subq.ph       s6, t2, t6      // tmp12 ...
-    addq.ph       s7, t2, t6      // tmp13
-    mulq_s.ph     s6, s6, t8      // ... tmp12 ...
-    addq.ph       t0, s4, s7      // tmp0
-    subq.ph       t6, s4, s7      // tmp3
-    muleq_s.w.phl v0, t1, s0      // tmp4 ...
-    muleq_s.w.phr t1, t1, s0      // ... tmp4 ...
-    shll_s.ph     s6, s6, 1       // x2
-    lw            s3, 112(a1)     // quantptr[DCTSIZE*7]
-    subq.ph       s6, s6, s7      // ... tmp12
-    muleq_s.w.phl v1, t7, s3      // tmp7 ...
-    muleq_s.w.phr t7, t7, s3      // ... tmp7 ...
-    ins           t1, v0, 16, 16  // ... tmp4
-    addq.ph       t2, s5, s6      // tmp1
-    subq.ph       t4, s5, s6      // tmp2
-    muleq_s.w.phl v0, t5, s2      // tmp6 ...
-    muleq_s.w.phr t5, t5, s2      // ... tmp6 ...
-    ins           t7, v1, 16, 16  // ... tmp7
-    addq.ph       s5, t1, t7      // z11
-    subq.ph       s6, t1, t7      // z12
-    muleq_s.w.phl v1, t3, s1      // tmp5 ...
-    muleq_s.w.phr t3, t3, s1      // ... tmp5 ...
-    ins           t5, v0, 16, 16  // ... tmp6
-    ins           t3, v1, 16, 16  // ... tmp5
-    addq.ph       s7, t5, t3      // z13
-    subq.ph       v0, t5, t3      // z10
-    addq.ph       t7, s5, s7      // tmp7
-    subq.ph       s5, s5, s7      // tmp11 ...
-    addq.ph       v1, v0, s6      // z5 ...
-    mulq_s.ph     s5, s5, t8      // ... tmp11
-    lw            t8, 8(AT)       // FIX(1.847759065)
-    lw            s4, 0(AT)       // FIX(1.082392200)
-    addq.ph       s0, t0, t7
-    subq.ph       s1, t0, t7
-    mulq_s.ph     v1, v1, t8      // ... z5
-    shll_s.ph     s5, s5, 1       // x2
-    lw            t8, 12(AT)      // FIX(-2.613125930)
-    sw            s0, 0(a2)       // wsptr[DCTSIZE*0]
-    shll_s.ph     v0, v0, 1       // x4
-    mulq_s.ph     v0, v0, t8      // tmp12 ...
-    mulq_s.ph     s4, s6, s4      // tmp10 ...
-    shll_s.ph     v1, v1, 1       // x2
-    addiu         a0, a0, 4
-    addiu         a1, a1, 4
-    sw            s1, 112(a2)     // wsptr[DCTSIZE*7]
-    shll_s.ph     s6, v0, 1       // x4
-    shll_s.ph     s4, s4, 1       // x2
-    addq.ph       s6, s6, v1      // ... tmp12
-    subq.ph       t5, s6, t7      // tmp6
-    subq.ph       s4, s4, v1      // ... tmp10
-    subq.ph       t3, s5, t5      // tmp5
-    addq.ph       s2, t2, t5
-    addq.ph       t1, s4, t3      // tmp4
-    subq.ph       s3, t2, t5
-    sw            s2, 16(a2)      // wsptr[DCTSIZE*1]
-    sw            s3, 96(a2)      // wsptr[DCTSIZE*6]
-    addq.ph       v0, t4, t3
-    subq.ph       v1, t4, t3
-    sw            v0, 32(a2)      // wsptr[DCTSIZE*2]
-    sw            v1, 80(a2)      // wsptr[DCTSIZE*5]
-    addq.ph       v0, t6, t1
-    subq.ph       v1, t6, t1
-    sw            v0, 64(a2)      // wsptr[DCTSIZE*4]
-    sw            v1, 48(a2)      // wsptr[DCTSIZE*3]
-
-2:
-    bne           a0, t9, 0b
-     addiu        a2, a2, 4
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j             ra
-     nop
-
-END(jsimd_idct_ifast_cols_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_ifast_rows_dspr2)
-/*
- * a0 = wsptr
- * a1 = output_buf
- * a2 = output_col
- * a3 = mips_idct_ifast_coefs
- */
-    SAVE_REGS_ON_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, s8, a3
-
-    addiu         t9, a0, 128     // end address
-    lui           s8, 0x8080
-    ori           s8, s8, 0x8080
-
-0:
-    lw            AT, 36(sp)      // restore $a3 (mips_idct_ifast_coefs)
-    lw            t0, 0(a0)       // wsptr[DCTSIZE*0+0/1]  b a
-    lw            s0, 16(a0)      // wsptr[DCTSIZE*1+0/1]  B A
-    lw            t2, 4(a0)       // wsptr[DCTSIZE*0+2/3]  d c
-    lw            s2, 20(a0)      // wsptr[DCTSIZE*1+2/3]  D C
-    lw            t4, 8(a0)       // wsptr[DCTSIZE*0+4/5]  f e
-    lw            s4, 24(a0)      // wsptr[DCTSIZE*1+4/5]  F E
-    lw            t6, 12(a0)      // wsptr[DCTSIZE*0+6/7]  h g
-    lw            s6, 28(a0)      // wsptr[DCTSIZE*1+6/7]  H G
-    precrq.ph.w   t1, s0, t0      // B b
-    ins           t0, s0, 16, 16  // A a
-    bnez          t1, 1f
-     or           s0, t2, s2
-    bnez          s0, 1f
-     or           s0, t4, s4
-    bnez          s0, 1f
-     or           s0, t6, s6
-    bnez          s0, 1f
-     shll_s.ph    s0, t0, 2       // A a
-    lw            a3, 0(a1)
-    lw            AT, 4(a1)
-    precrq.ph.w   t0, s0, s0      // A A
-    ins           s0, s0, 16, 16  // a a
-    addu          a3, a3, a2
-    addu          AT, AT, a2
-    precrq.qb.ph  t0, t0, t0      // A A A A
-    precrq.qb.ph  s0, s0, s0      // a a a a
-    addu.qb       s0, s0, s8
-    addu.qb       t0, t0, s8
-    sw            s0, 0(a3)
-    sw            s0, 4(a3)
-    sw            t0, 0(AT)
-    sw            t0, 4(AT)
-    addiu         a0, a0, 32
-    bne           a0, t9, 0b
-     addiu        a1, a1, 8
-    b             2f
-     nop
-
-1:
-    precrq.ph.w   t3, s2, t2
-    ins           t2, s2, 16, 16
-    precrq.ph.w   t5, s4, t4
-    ins           t4, s4, 16, 16
-    precrq.ph.w   t7, s6, t6
-    ins           t6, s6, 16, 16
-    lw            t8, 4(AT)       // FIX(1.414213562)
-    addq.ph       s4, t0, t4      // tmp10
-    subq.ph       s5, t0, t4      // tmp11
-    subq.ph       s6, t2, t6      // tmp12 ...
-    addq.ph       s7, t2, t6      // tmp13
-    mulq_s.ph     s6, s6, t8      // ... tmp12 ...
-    addq.ph       t0, s4, s7      // tmp0
-    subq.ph       t6, s4, s7      // tmp3
-    shll_s.ph     s6, s6, 1       // x2
-    subq.ph       s6, s6, s7      // ... tmp12
-    addq.ph       t2, s5, s6      // tmp1
-    subq.ph       t4, s5, s6      // tmp2
-    addq.ph       s5, t1, t7      // z11
-    subq.ph       s6, t1, t7      // z12
-    addq.ph       s7, t5, t3      // z13
-    subq.ph       v0, t5, t3      // z10
-    addq.ph       t7, s5, s7      // tmp7
-    subq.ph       s5, s5, s7      // tmp11 ...
-    addq.ph       v1, v0, s6      // z5 ...
-    mulq_s.ph     s5, s5, t8      // ... tmp11
-    lw            t8, 8(AT)       // FIX(1.847759065)
-    lw            s4, 0(AT)       // FIX(1.082392200)
-    addq.ph       s0, t0, t7      // tmp0 + tmp7
-    subq.ph       s7, t0, t7      // tmp0 - tmp7
-    mulq_s.ph     v1, v1, t8      // ... z5
-    lw            a3, 0(a1)
-    lw            t8, 12(AT)      // FIX(-2.613125930)
-    shll_s.ph     s5, s5, 1       // x2
-    addu          a3, a3, a2
-    shll_s.ph     v0, v0, 1       // x4
-    mulq_s.ph     v0, v0, t8      // tmp12 ...
-    mulq_s.ph     s4, s6, s4      // tmp10 ...
-    shll_s.ph     v1, v1, 1       // x2
-    addiu         a0, a0, 32
-    addiu         a1, a1, 8
-    shll_s.ph     s6, v0, 1       // x4
-    shll_s.ph     s4, s4, 1       // x2
-    addq.ph       s6, s6, v1      // ... tmp12
-    shll_s.ph     s0, s0, 2
-    subq.ph       t5, s6, t7      // tmp6
-    subq.ph       s4, s4, v1      // ... tmp10
-    subq.ph       t3, s5, t5      // tmp5
-    shll_s.ph     s7, s7, 2
-    addq.ph       t1, s4, t3      // tmp4
-    addq.ph       s1, t2, t5      // tmp1 + tmp6
-    subq.ph       s6, t2, t5      // tmp1 - tmp6
-    addq.ph       s2, t4, t3      // tmp2 + tmp5
-    subq.ph       s5, t4, t3      // tmp2 - tmp5
-    addq.ph       s4, t6, t1      // tmp3 + tmp4
-    subq.ph       s3, t6, t1      // tmp3 - tmp4
-    shll_s.ph     s1, s1, 2
-    shll_s.ph     s2, s2, 2
-    shll_s.ph     s3, s3, 2
-    shll_s.ph     s4, s4, 2
-    shll_s.ph     s5, s5, 2
-    shll_s.ph     s6, s6, 2
-    precrq.ph.w   t0, s1, s0      // B A
-    ins           s0, s1, 16, 16  // b a
-    precrq.ph.w   t2, s3, s2      // D C
-    ins           s2, s3, 16, 16  // d c
-    precrq.ph.w   t4, s5, s4      // F E
-    ins           s4, s5, 16, 16  // f e
-    precrq.ph.w   t6, s7, s6      // H G
-    ins           s6, s7, 16, 16  // h g
-    precrq.qb.ph  t0, t2, t0      // D C B A
-    precrq.qb.ph  s0, s2, s0      // d c b a
-    precrq.qb.ph  t4, t6, t4      // H G F E
-    precrq.qb.ph  s4, s6, s4      // h g f e
-    addu.qb       s0, s0, s8
-    addu.qb       s4, s4, s8
-    sw            s0, 0(a3)       // outptr[0/1/2/3]       d c b a
-    sw            s4, 4(a3)       // outptr[4/5/6/7]       h g f e
-    lw            a3, -4(a1)
-    addu.qb       t0, t0, s8
-    addu          a3, a3, a2
-    addu.qb       t4, t4, s8
-    sw            t0, 0(a3)       // outptr[0/1/2/3]       D C B A
-    bne           a0, t9, 0b
-     sw           t4, 4(a3)       // outptr[4/5/6/7]       H G F E
-
-2:
-
-    RESTORE_REGS_FROM_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, s8, a3
-
-    j             ra
-     nop
-
-END(jsimd_idct_ifast_rows_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_fdct_islow_dspr2)
-/*
- * a0 = data
- */
-    SAVE_REGS_ON_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, s8
-
-    lui         t0, 6437
-    ori         t0, 2260
-    lui         t1, 9633
-    ori         t1, 11363
-    lui         t2, 0xd39e
-    ori         t2, 0xe6dc
-    lui         t3, 0xf72d
-    ori         t3, 9633
-    lui         t4, 2261
-    ori         t4, 9633
-    lui         t5, 0xd39e
-    ori         t5, 6437
-    lui         t6, 9633
-    ori         t6, 0xd39d
-    lui         t7, 0xe6dc
-    ori         t7, 2260
-    lui         t8, 4433
-    ori         t8, 10703
-    lui         t9, 0xd630
-    ori         t9, 4433
-    li          s8, 8
-    move        a1, a0
-1:
-    lw          s0, 0(a1)       // tmp0 = 1|0
-    lw          s1, 4(a1)       // tmp1 = 3|2
-    lw          s2, 8(a1)       // tmp2 = 5|4
-    lw          s3, 12(a1)      // tmp3 = 7|6
-    packrl.ph   s1, s1, s1      // tmp1 = 2|3
-    packrl.ph   s3, s3, s3      // tmp3 = 6|7
-    subq.ph     s7, s1, s2      // tmp7 = 2-5|3-4 = t5|t4
-    subq.ph     s5, s0, s3      // tmp5 = 1-6|0-7 = t6|t7
-    mult        $0, $0          // ac0  = 0
-    dpa.w.ph    $ac0, s7, t0    // ac0 += t5*  6437 + t4*  2260
-    dpa.w.ph    $ac0, s5, t1    // ac0 += t6*  9633 + t7* 11363
-    mult        $ac1, $0, $0    // ac1  = 0
-    dpa.w.ph    $ac1, s7, t2    // ac1 += t5*-11362 + t4* -6436
-    dpa.w.ph    $ac1, s5, t3    // ac1 += t6* -2259 + t7*  9633
-    mult        $ac2, $0, $0    // ac2  = 0
-    dpa.w.ph    $ac2, s7, t4    // ac2 += t5*  2261 + t4*  9633
-    dpa.w.ph    $ac2, s5, t5    // ac2 += t6*-11362 + t7*  6437
-    mult        $ac3, $0, $0    // ac3  = 0
-    dpa.w.ph    $ac3, s7, t6    // ac3 += t5*  9633 + t4*-11363
-    dpa.w.ph    $ac3, s5, t7    // ac3 += t6* -6436 + t7*  2260
-    addq.ph     s6, s1, s2      // tmp6 = 2+5|3+4 = t2|t3
-    addq.ph     s4, s0, s3      // tmp4 = 1+6|0+7 = t1|t0
-    extr_r.w    s0, $ac0, 11    // tmp0 = (ac0 + 1024) >> 11
-    extr_r.w    s1, $ac1, 11    // tmp1 = (ac1 + 1024) >> 11
-    extr_r.w    s2, $ac2, 11    // tmp2 = (ac2 + 1024) >> 11
-    extr_r.w    s3, $ac3, 11    // tmp3 = (ac3 + 1024) >> 11
-    addq.ph     s5, s4, s6      // tmp5 = t1+t2|t0+t3 = t11|t10
-    subq.ph     s7, s4, s6      // tmp7 = t1-t2|t0-t3 = t12|t13
-    sh          s0, 2(a1)
-    sh          s1, 6(a1)
-    sh          s2, 10(a1)
-    sh          s3, 14(a1)
-    mult        $0, $0          // ac0  = 0
-    dpa.w.ph    $ac0, s7, t8    // ac0 += t12*  4433 + t13* 10703
-    mult        $ac1, $0, $0    // ac1  = 0
-    dpa.w.ph    $ac1, s7, t9    // ac1 += t12*-10704 + t13*  4433
-    sra         s4, s5, 16      // tmp4 = t11
-    addiu       a1, a1, 16
-    addiu       s8, s8, -1
-    extr_r.w    s0, $ac0, 11    // tmp0 = (ac0 + 1024) >> 11
-    extr_r.w    s1, $ac1, 11    // tmp1 = (ac1 + 1024) >> 11
-    addu        s2, s5, s4      // tmp2 = t10 + t11
-    subu        s3, s5, s4      // tmp3 = t10 - t11
-    sll         s2, s2, 2       // tmp2 = (t10 + t11) << 2
-    sll         s3, s3, 2       // tmp3 = (t10 - t11) << 2
-    sh          s2, -16(a1)
-    sh          s3, -8(a1)
-    sh          s0, -12(a1)
-    bgtz        s8, 1b
-     sh         s1, -4(a1)
-    li          t0, 2260
-    li          t1, 11363
-    li          t2, 9633
-    li          t3, 6436
-    li          t4, 6437
-    li          t5, 2261
-    li          t6, 11362
-    li          t7, 2259
-    li          t8, 4433
-    li          t9, 10703
-    li          a1, 10704
-    li          s8, 8
-
-2:
-    lh          a2, 0(a0)       // 0
-    lh          a3, 16(a0)      // 8
-    lh          v0, 32(a0)      // 16
-    lh          v1, 48(a0)      // 24
-    lh          s4, 64(a0)      // 32
-    lh          s5, 80(a0)      // 40
-    lh          s6, 96(a0)      // 48
-    lh          s7, 112(a0)     // 56
-    addu        s2, v0, s5      // tmp2 = 16 + 40
-    subu        s5, v0, s5      // tmp5 = 16 - 40
-    addu        s3, v1, s4      // tmp3 = 24 + 32
-    subu        s4, v1, s4      // tmp4 = 24 - 32
-    addu        s0, a2, s7      // tmp0 =  0 + 56
-    subu        s7, a2, s7      // tmp7 =  0 - 56
-    addu        s1, a3, s6      // tmp1 =  8 + 48
-    subu        s6, a3, s6      // tmp6 =  8 - 48
-    addu        a2, s0, s3      // tmp10 = tmp0 + tmp3
-    subu        v1, s0, s3      // tmp13 = tmp0 - tmp3
-    addu        a3, s1, s2      // tmp11 = tmp1 + tmp2
-    subu        v0, s1, s2      // tmp12 = tmp1 - tmp2
-    mult        s7, t1          // ac0  = tmp7 * c1
-    madd        s4, t0          // ac0 += tmp4 * c0
-    madd        s5, t4          // ac0 += tmp5 * c4
-    madd        s6, t2          // ac0 += tmp6 * c2
-    mult        $ac1, s7, t2    // ac1  = tmp7 * c2
-    msub        $ac1, s4, t3    // ac1 -= tmp4 * c3
-    msub        $ac1, s5, t6    // ac1 -= tmp5 * c6
-    msub        $ac1, s6, t7    // ac1 -= tmp6 * c7
-    mult        $ac2, s7, t4    // ac2  = tmp7 * c4
-    madd        $ac2, s4, t2    // ac2 += tmp4 * c2
-    madd        $ac2, s5, t5    // ac2 += tmp5 * c5
-    msub        $ac2, s6, t6    // ac2 -= tmp6 * c6
-    mult        $ac3, s7, t0    // ac3  = tmp7 * c0
-    msub        $ac3, s4, t1    // ac3 -= tmp4 * c1
-    madd        $ac3, s5, t2    // ac3 += tmp5 * c2
-    msub        $ac3, s6, t3    // ac3 -= tmp6 * c3
-    extr_r.w    s0, $ac0, 15    // tmp0 = (ac0 + 16384) >> 15
-    extr_r.w    s1, $ac1, 15    // tmp1 = (ac1 + 16384) >> 15
-    extr_r.w    s2, $ac2, 15    // tmp2 = (ac2 + 16384) >> 15
-    extr_r.w    s3, $ac3, 15    // tmp3 = (ac3 + 16384) >> 15
-    addiu       s8, s8, -1
-    addu        s4, a2, a3      // tmp4 = tmp10 + tmp11
-    subu        s5, a2, a3      // tmp5 = tmp10 - tmp11
-    sh          s0, 16(a0)
-    sh          s1, 48(a0)
-    sh          s2, 80(a0)
-    sh          s3, 112(a0)
-    mult        v0, t8          // ac0  = tmp12 * c8
-    madd        v1, t9          // ac0 += tmp13 * c9
-    mult        $ac1, v1, t8    // ac1  = tmp13 * c8
-    msub        $ac1, v0, a1    // ac1 -= tmp12 * c10
-    addiu       a0, a0, 2
-    extr_r.w    s6, $ac0, 15    // tmp6 = (ac0 + 16384) >> 15
-    extr_r.w    s7, $ac1, 15    // tmp7 = (ac1 + 16384) >> 15
-    shra_r.w    s4, s4, 2       // tmp4 = (tmp4 + 2) >> 2
-    shra_r.w    s5, s5, 2       // tmp5 = (tmp5 + 2) >> 2
-    sh          s4, -2(a0)
-    sh          s5, 62(a0)
-    sh          s6, 30(a0)
-    bgtz        s8, 2b
-     sh         s7, 94(a0)
-
-    RESTORE_REGS_FROM_STACK 40, s0, s1, s2, s3, s4, s5, s6, s7, s8
-
-    jr          ra
-     nop
-
-END(jsimd_fdct_islow_dspr2)
-
-
-/**************************************************************************/
-LEAF_DSPR2(jsimd_fdct_ifast_dspr2)
-/*
- * a0 = data
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 8, s0, s1
-
-    li          a1, 0x014e014e  // FIX_1_306562965 (334 << 16)|(334 & 0xffff)
-    li          a2, 0x008b008b  // FIX_0_541196100 (139 << 16)|(139 & 0xffff)
-    li          a3, 0x00620062  // FIX_0_382683433 (98 << 16) |(98 & 0xffff)
-    li          s1, 0x00b500b5  // FIX_0_707106781 (181 << 16)|(181 & 0xffff)
-
-    move        v0, a0
-    addiu       v1, v0, 128     // end address
-
-0:
-    lw          t0, 0(v0)       // tmp0 = 1|0
-    lw          t1, 4(v0)       // tmp1 = 3|2
-    lw          t2, 8(v0)       // tmp2 = 5|4
-    lw          t3, 12(v0)      // tmp3 = 7|6
-    packrl.ph   t1, t1, t1      // tmp1 = 2|3
-    packrl.ph   t3, t3, t3      // tmp3 = 6|7
-    subq.ph     t7, t1, t2      // tmp7 = 2-5|3-4 = t5|t4
-    subq.ph     t5, t0, t3      // tmp5 = 1-6|0-7 = t6|t7
-    addq.ph     t6, t1, t2      // tmp6 = 2+5|3+4 = t2|t3
-    addq.ph     t4, t0, t3      // tmp4 = 1+6|0+7 = t1|t0
-    addq.ph     t8, t4, t6      // tmp5 = t1+t2|t0+t3 = t11|t10
-    subq.ph     t9, t4, t6      // tmp7 = t1-t2|t0-t3 = t12|t13
-    sra         t4, t8, 16      // tmp4 = t11
-    mult        $0, $0          // ac0  = 0
-    dpa.w.ph    $ac0, t9, s1
-    mult        $ac1, $0, $0    // ac1  = 0
-    dpa.w.ph    $ac1, t7, a3    // ac1 += t4*98 + t5*98
-    dpsx.w.ph   $ac1, t5, a3    // ac1 += t6*98 + t7*98
-    mult        $ac2, $0, $0    // ac2  = 0
-    dpa.w.ph    $ac2, t7, a2    // ac2 += t4*139 + t5*139
-    mult        $ac3, $0, $0    // ac3  = 0
-    dpa.w.ph    $ac3, t5, a1    // ac3 += t6*334 + t7*334
-    precrq.ph.w t0, t5, t7      // t0 = t5|t6
-    addq.ph     t2, t8, t4      // tmp2 = t10 + t11
-    subq.ph     t3, t8, t4      // tmp3 = t10 - t11
-    extr.w      t4, $ac0, 8
-    mult        $0, $0          // ac0  = 0
-    dpa.w.ph    $ac0, t0, s1    // ac0 += t5*181 + t6*181
-    extr.w      t0, $ac1, 8     // t0 = z5
-    extr.w      t1, $ac2, 8     // t1 = MULTIPLY(tmp10, 139)
-    extr.w      t7, $ac3, 8     // t2 = MULTIPLY(tmp12, 334)
-    extr.w      t8, $ac0, 8     // t8 = z3 = MULTIPLY(tmp11, 181)
-    add         t6, t1, t0      // t6 = z2
-    add         t7, t7, t0      // t7 = z4
-    subq.ph     t0, t5, t8      // t0 = z13 = tmp7 - z3
-    addq.ph     t8, t5, t8      // t9 = z11 = tmp7 + z3
-    addq.ph     t1, t0, t6      // t1 = z13 + z2
-    subq.ph     t6, t0, t6      // t6 = z13 - z2
-    addq.ph     t0, t8, t7      // t0 = z11 + z4
-    subq.ph     t7, t8, t7      // t7 = z11 - z4
-    addq.ph     t5, t4, t9
-    subq.ph     t4, t9, t4
-    sh          t2, 0(v0)
-    sh          t5, 4(v0)
-    sh          t3, 8(v0)
-    sh          t4, 12(v0)
-    sh          t1, 10(v0)
-    sh          t6, 6(v0)
-    sh          t0, 2(v0)
-    sh          t7, 14(v0)
-    addiu       v0, 16
-    bne         v1, v0, 0b
-     nop
-    move        v0, a0
-    addiu       v1, v0, 16
-
-1:
-    lh          t0, 0(v0)       // 0
-    lh          t1, 16(v0)      // 8
-    lh          t2, 32(v0)      // 16
-    lh          t3, 48(v0)      // 24
-    lh          t4, 64(v0)      // 32
-    lh          t5, 80(v0)      // 40
-    lh          t6, 96(v0)      // 48
-    lh          t7, 112(v0)     // 56
-    add         t8, t0, t7      // t8 = tmp0
-    sub         t7, t0, t7      // t7 = tmp7
-    add         t0, t1, t6      // t0 = tmp1
-    sub         t1, t1, t6      // t1 = tmp6
-    add         t6, t2, t5      // t6 = tmp2
-    sub         t5, t2, t5      // t5 = tmp5
-    add         t2, t3, t4      // t2 = tmp3
-    sub         t3, t3, t4      // t3 = tmp4
-    add         t4, t8, t2      // t4 = tmp10 = tmp0 + tmp3
-    sub         t8, t8, t2      // t8 = tmp13 = tmp0 - tmp3
-    sub         s0, t0, t6      // s0 = tmp12 = tmp1 - tmp2
-    ins         t8, s0, 16, 16  // t8 = tmp12|tmp13
-    add         t2, t0, t6      // t2 = tmp11 = tmp1 + tmp2
-    mult        $0, $0          // ac0  = 0
-    dpa.w.ph    $ac0, t8, s1    // ac0 += t12*181 + t13*181
-    add         s0, t4, t2      // t8 = tmp10+tmp11
-    sub         t4, t4, t2      // t4 = tmp10-tmp11
-    sh          s0, 0(v0)
-    sh          t4, 64(v0)
-    extr.w      t2, $ac0, 8     // z1 = MULTIPLY(tmp12+tmp13, FIX_0_707106781)
-    addq.ph     t4, t8, t2      // t9 = tmp13 + z1
-    subq.ph     t8, t8, t2      // t2 = tmp13 - z1
-    sh          t4, 32(v0)
-    sh          t8, 96(v0)
-    add         t3, t3, t5      // t3 = tmp10 = tmp4 + tmp5
-    add         t0, t5, t1      // t0 = tmp11 = tmp5 + tmp6
-    add         t1, t1, t7      // t1 = tmp12 = tmp6 + tmp7
-    andi        t4, a1, 0xffff
-    mul         s0, t1, t4
-    sra         s0, s0, 8       // s0 = z4 = MULTIPLY(tmp12, FIX_1_306562965)
-    ins         t1, t3, 16, 16  // t1 = tmp10|tmp12
-    mult        $0, $0          // ac0  = 0
-    mulsa.w.ph  $ac0, t1, a3    // ac0 += t10*98 - t12*98
-    extr.w      t8, $ac0, 8     // z5 = MULTIPLY(tmp10-tmp12, FIX_0_382683433)
-    add         t2, t7, t8      // t2 = tmp7 + z5
-    sub         t7, t7, t8      // t7 = tmp7 - z5
-    andi        t4, a2, 0xffff
-    mul         t8, t3, t4
-    sra         t8, t8, 8       // t8 = z2 = MULTIPLY(tmp10, FIX_0_541196100)
-    andi        t4, s1, 0xffff
-    mul         t6, t0, t4
-    sra         t6, t6, 8       // t6 = z3 = MULTIPLY(tmp11, FIX_0_707106781)
-    add         t0, t6, t8      // t0 = z3 + z2
-    sub         t1, t6, t8      // t1 = z3 - z2
-    add         t3, t6, s0      // t3 = z3 + z4
-    sub         t4, t6, s0      // t4 = z3 - z4
-    sub         t5, t2, t1      // t5 = dataptr[5]
-    sub         t6, t7, t0      // t6 = dataptr[3]
-    add         t3, t2, t3      // t3 = dataptr[1]
-    add         t4, t7, t4      // t4 = dataptr[7]
-    sh          t5, 80(v0)
-    sh          t6, 48(v0)
-    sh          t3, 16(v0)
-    sh          t4, 112(v0)
-    addiu       v0, 2
-    bne         v0, v1, 1b
-     nop
-
-    RESTORE_REGS_FROM_STACK 8, s0, s1
-
-    j           ra
-     nop
-END(jsimd_fdct_ifast_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_quantize_dspr2)
-/*
- * a0 = coef_block
- * a1 = divisors
- * a2 = workspace
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 16, s0, s1, s2
-
-    addiu       v0, a2, 124     // v0 = workspace_end
-    lh          t0, 0(a2)
-    lh          t1, 0(a1)
-    lh          t2, 128(a1)
-    sra         t3, t0, 15
-    sll         t3, t3, 1
-    addiu       t3, t3, 1
-    mul         t0, t0, t3
-    lh          t4, 384(a1)
-    lh          t5, 130(a1)
-    lh          t6, 2(a2)
-    lh          t7, 2(a1)
-    lh          t8, 386(a1)
-
-1:
-    andi        t1, 0xffff
-    add         t9, t0, t2
-    andi        t9, 0xffff
-    mul         v1, t9, t1
-    sra         s0, t6, 15
-    sll         s0, s0, 1
-    addiu       s0, s0, 1
-    addiu       t9, t4, 16
-    srav        v1, v1, t9
-    mul         v1, v1, t3
-    mul         t6, t6, s0
-    andi        t7, 0xffff
-    addiu       a2, a2, 4
-    addiu       a1, a1, 4
-    add         s1, t6, t5
-    andi        s1, 0xffff
-    sh          v1, 0(a0)
-
-    mul         s2, s1, t7
-    addiu       s1, t8, 16
-    srav        s2, s2, s1
-    mul         s2, s2, s0
-    lh          t0, 0(a2)
-    lh          t1, 0(a1)
-    sra         t3, t0, 15
-    sll         t3, t3, 1
-    addiu       t3, t3, 1
-    mul         t0, t0, t3
-    lh          t2, 128(a1)
-    lh          t4, 384(a1)
-    lh          t5, 130(a1)
-    lh          t8, 386(a1)
-    lh          t6, 2(a2)
-    lh          t7, 2(a1)
-    sh          s2, 2(a0)
-    lh          t0, 0(a2)
-    sra         t3, t0, 15
-    sll         t3, t3, 1
-    addiu       t3, t3, 1
-    mul         t0, t0, t3
-    bne         a2, v0, 1b
-     addiu      a0, a0, 4
-
-    andi        t1, 0xffff
-    add         t9, t0, t2
-    andi        t9, 0xffff
-    mul         v1, t9, t1
-    sra         s0, t6, 15
-    sll         s0, s0, 1
-    addiu       s0, s0, 1
-    addiu       t9, t4, 16
-    srav        v1, v1, t9
-    mul         v1, v1, t3
-    mul         t6, t6, s0
-    andi        t7, 0xffff
-    sh          v1, 0(a0)
-    add         s1, t6, t5
-    andi        s1, 0xffff
-    mul         s2, s1, t7
-    addiu       s1, t8, 16
-    addiu       a2, a2, 4
-    addiu       a1, a1, 4
-    srav        s2, s2, s1
-    mul         s2, s2, s0
-    sh          s2, 2(a0)
-
-    RESTORE_REGS_FROM_STACK 16, s0, s1, s2
-
-    j           ra
-     nop
-
-END(jsimd_quantize_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_quantize_float_dspr2)
-/*
- * a0 = coef_block
- * a1 = divisors
- * a2 = workspace
- */
-    .set at
-
-    li          t1, 0x46800100  // integer representation 16384.5
-    mtc1        t1, f0
-    li          t0, 63
-0:
-    lwc1        f2, 0(a2)
-    lwc1        f10, 0(a1)
-    lwc1        f4, 4(a2)
-    lwc1        f12, 4(a1)
-    lwc1        f6, 8(a2)
-    lwc1        f14, 8(a1)
-    lwc1        f8, 12(a2)
-    lwc1        f16, 12(a1)
-    madd.s      f2, f0, f2, f10
-    madd.s      f4, f0, f4, f12
-    madd.s      f6, f0, f6, f14
-    madd.s      f8, f0, f8, f16
-    lwc1        f10, 16(a1)
-    lwc1        f12, 20(a1)
-    trunc.w.s   f2, f2
-    trunc.w.s   f4, f4
-    trunc.w.s   f6, f6
-    trunc.w.s   f8, f8
-    lwc1        f14, 24(a1)
-    lwc1        f16, 28(a1)
-    mfc1        t1, f2
-    mfc1        t2, f4
-    mfc1        t3, f6
-    mfc1        t4, f8
-    lwc1        f2, 16(a2)
-    lwc1        f4, 20(a2)
-    lwc1        f6, 24(a2)
-    lwc1        f8, 28(a2)
-    madd.s      f2, f0, f2, f10
-    madd.s      f4, f0, f4, f12
-    madd.s      f6, f0, f6, f14
-    madd.s      f8, f0, f8, f16
-    addiu       t1, t1, -16384
-    addiu       t2, t2, -16384
-    addiu       t3, t3, -16384
-    addiu       t4, t4, -16384
-    trunc.w.s   f2, f2
-    trunc.w.s   f4, f4
-    trunc.w.s   f6, f6
-    trunc.w.s   f8, f8
-    sh          t1, 0(a0)
-    sh          t2, 2(a0)
-    sh          t3, 4(a0)
-    sh          t4, 6(a0)
-    mfc1        t1, f2
-    mfc1        t2, f4
-    mfc1        t3, f6
-    mfc1        t4, f8
-    addiu       t0, t0, -8
-    addiu       a2, a2, 32
-    addiu       a1, a1, 32
-    addiu       t1, t1, -16384
-    addiu       t2, t2, -16384
-    addiu       t3, t3, -16384
-    addiu       t4, t4, -16384
-    sh          t1, 8(a0)
-    sh          t2, 10(a0)
-    sh          t3, 12(a0)
-    sh          t4, 14(a0)
-    bgez        t0, 0b
-     addiu      a0, a0, 16
-
-    j           ra
-     nop
-
-END(jsimd_quantize_float_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_2x2_dspr2)
-/*
- * a0 = compptr->dct_table
- * a1 = coef_block
- * a2 = output_buf
- * a3 = output_col
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 24, s0, s1, s2, s3, s4, s5
-
-    addiu       sp, sp, -40
-    move        v0, sp
-    addiu       s2, zero, 29692
-    addiu       s3, zero, -10426
-    addiu       s4, zero, 6967
-    addiu       s5, zero, -5906
-    lh          t0, 0(a1)       // t0 = inptr[DCTSIZE*0]
-    lh          t5, 0(a0)       // t5 = quantptr[DCTSIZE*0]
-    lh          t1, 48(a1)      // t1 = inptr[DCTSIZE*3]
-    lh          t6, 48(a0)      // t6 = quantptr[DCTSIZE*3]
-    mul         t4, t5, t0
-    lh          t0, 16(a1)      // t0 = inptr[DCTSIZE*1]
-    lh          t5, 16(a0)      // t5 = quantptr[DCTSIZE*1]
-    mul         t6, t6, t1
-    mul         t5, t5, t0
-    lh          t2, 80(a1)      // t2 = inptr[DCTSIZE*5]
-    lh          t7, 80(a0)      // t7 = quantptr[DCTSIZE*5]
-    lh          t3, 112(a1)     // t3 = inptr[DCTSIZE*7]
-    lh          t8, 112(a0)     // t8 = quantptr[DCTSIZE*7]
-    mul         t7, t7, t2
-    mult        zero, zero
-    mul         t8, t8, t3
-    li          s0, 0x73FCD746  // s0 = (29692 << 16) | (-10426 & 0xffff)
-    li          s1, 0x1B37E8EE  // s1 = (6967 << 16) | (-5906 & 0xffff)
-    ins         t6, t5, 16, 16  // t6 = t5|t6
-    sll         t4, t4, 15
-    dpa.w.ph    $ac0, t6, s0
-    lh          t1, 2(a1)
-    lh          t6, 2(a0)
-    ins         t8, t7, 16, 16  // t8 = t7|t8
-    dpa.w.ph    $ac0, t8, s1
-    mflo        t0, $ac0
-    mul         t5, t6, t1
-    lh          t1, 18(a1)
-    lh          t6, 18(a0)
-    lh          t2, 50(a1)
-    lh          t7, 50(a0)
-    mul         t6, t6, t1
-    subu        t8, t4, t0
-    mul         t7, t7, t2
-    addu        t0, t4, t0
-    shra_r.w    t0, t0, 13
-    lh          t1, 82(a1)
-    lh          t2, 82(a0)
-    lh          t3, 114(a1)
-    lh          t4, 114(a0)
-    shra_r.w    t8, t8, 13
-    mul         t1, t1, t2
-    mul         t3, t3, t4
-    sw          t0, 0(v0)
-    sw          t8, 20(v0)
-    sll         t4, t5, 15
-    ins         t7, t6, 16, 16
-    mult        zero, zero
-    dpa.w.ph    $ac0, t7, s0
-    ins         t3, t1, 16, 16
-    lh          t1, 6(a1)
-    lh          t6, 6(a0)
-    dpa.w.ph    $ac0, t3, s1
-    mflo        t0, $ac0
-    mul         t5, t6, t1
-    lh          t1, 22(a1)
-    lh          t6, 22(a0)
-    lh          t2, 54(a1)
-    lh          t7, 54(a0)
-    mul         t6, t6, t1
-    subu        t8, t4, t0
-    mul         t7, t7, t2
-    addu        t0, t4, t0
-    shra_r.w    t0, t0, 13
-    lh          t1, 86(a1)
-    lh          t2, 86(a0)
-    lh          t3, 118(a1)
-    lh          t4, 118(a0)
-    shra_r.w    t8, t8, 13
-    mul         t1, t1, t2
-    mul         t3, t3, t4
-    sw          t0, 4(v0)
-    sw          t8, 24(v0)
-    sll         t4, t5, 15
-    ins         t7, t6, 16, 16
-    mult        zero, zero
-    dpa.w.ph    $ac0, t7, s0
-    ins         t3, t1, 16, 16
-    lh          t1, 10(a1)
-    lh          t6, 10(a0)
-    dpa.w.ph    $ac0, t3, s1
-    mflo        t0, $ac0
-    mul         t5, t6, t1
-    lh          t1, 26(a1)
-    lh          t6, 26(a0)
-    lh          t2, 58(a1)
-    lh          t7, 58(a0)
-    mul         t6, t6, t1
-    subu        t8, t4, t0
-    mul         t7, t7, t2
-    addu        t0, t4, t0
-    shra_r.w    t0, t0, 13
-    lh          t1, 90(a1)
-    lh          t2, 90(a0)
-    lh          t3, 122(a1)
-    lh          t4, 122(a0)
-    shra_r.w    t8, t8, 13
-    mul         t1, t1, t2
-    mul         t3, t3, t4
-    sw          t0, 8(v0)
-    sw          t8, 28(v0)
-    sll         t4, t5, 15
-    ins         t7, t6, 16, 16
-    mult        zero, zero
-    dpa.w.ph    $ac0, t7, s0
-    ins         t3, t1, 16, 16
-    lh          t1, 14(a1)
-    lh          t6, 14(a0)
-    dpa.w.ph    $ac0, t3, s1
-    mflo        t0, $ac0
-    mul         t5, t6, t1
-    lh          t1, 30(a1)
-    lh          t6, 30(a0)
-    lh          t2, 62(a1)
-    lh          t7, 62(a0)
-    mul         t6, t6, t1
-    subu        t8, t4, t0
-    mul         t7, t7, t2
-    addu        t0, t4, t0
-    shra_r.w    t0, t0, 13
-    lh          t1, 94(a1)
-    lh          t2, 94(a0)
-    lh          t3, 126(a1)
-    lh          t4, 126(a0)
-    shra_r.w    t8, t8, 13
-    mul         t1, t1, t2
-    mul         t3, t3, t4
-    sw          t0, 12(v0)
-    sw          t8, 32(v0)
-    sll         t4, t5, 15
-    ins         t7, t6, 16, 16
-    mult        zero, zero
-    dpa.w.ph    $ac0, t7, s0
-    ins         t3, t1, 16, 16
-    dpa.w.ph    $ac0, t3, s1
-    mflo        t0, $ac0
-    lw          t9, 0(a2)
-    lw          t3, 0(v0)
-    lw          t7, 4(v0)
-    lw          t1, 8(v0)
-    addu        t9, t9, a3
-    sll         t3, t3, 15
-    subu        t8, t4, t0
-    addu        t0, t4, t0
-    shra_r.w    t0, t0, 13
-    shra_r.w    t8, t8, 13
-    sw          t0, 16(v0)
-    sw          t8, 36(v0)
-    lw          t5, 12(v0)
-    lw          t6, 16(v0)
-    mult        t7, s2
-    madd        t1, s3
-    madd        t5, s4
-    madd        t6, s5
-    lw          t5, 24(v0)
-    lw          t7, 28(v0)
-    mflo        t0, $ac0
-    lw          t8, 32(v0)
-    lw          t2, 36(v0)
-    mult        $ac1, t5, s2
-    madd        $ac1, t7, s3
-    madd        $ac1, t8, s4
-    madd        $ac1, t2, s5
-    addu        t1, t3, t0
-    subu        t6, t3, t0
-    shra_r.w    t1, t1, 20
-    shra_r.w    t6, t6, 20
-    mflo        t4, $ac1
-    shll_s.w    t1, t1, 24
-    shll_s.w    t6, t6, 24
-    sra         t1, t1, 24
-    sra         t6, t6, 24
-    addiu       t1, t1, 128
-    addiu       t6, t6, 128
-    lw          t0, 20(v0)
-    sb          t1, 0(t9)
-    sb          t6, 1(t9)
-    sll         t0, t0, 15
-    lw          t9, 4(a2)
-    addu        t1, t0, t4
-    subu        t6, t0, t4
-    addu        t9, t9, a3
-    shra_r.w    t1, t1, 20
-    shra_r.w    t6, t6, 20
-    shll_s.w    t1, t1, 24
-    shll_s.w    t6, t6, 24
-    sra         t1, t1, 24
-    sra         t6, t6, 24
-    addiu       t1, t1, 128
-    addiu       t6, t6, 128
-    sb          t1, 0(t9)
-    sb          t6, 1(t9)
-    addiu       sp, sp, 40
-
-    RESTORE_REGS_FROM_STACK 24, s0, s1, s2, s3, s4, s5
-
-    j           ra
-     nop
-
-END(jsimd_idct_2x2_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_4x4_dspr2)
-/*
- * a0     = compptr->dct_table
- * a1     = coef_block
- * a2     = output_buf
- * a3     = output_col
- * 16(sp) = workspace[DCTSIZE*4];  // buffers data between passes
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    lw          v1, 48(sp)
-    move        t0, a1
-    move        t1, v1
-    li          t9, 4
-    li          s0, 0x2e75f93e
-    li          s1, 0x21f9ba79
-    li          s2, 0xecc2efb0
-    li          s3, 0x52031ccd
-
-0:
-    lh          s6, 32(t0)      // inptr[DCTSIZE*2]
-    lh          t6, 32(a0)      // quantptr[DCTSIZE*2]
-    lh          s7, 96(t0)      // inptr[DCTSIZE*6]
-    lh          t7, 96(a0)      // quantptr[DCTSIZE*6]
-    mul         t6, s6, t6      // z2 = (inptr[DCTSIZE*2] * quantptr[DCTSIZE*2])
-    lh          s4, 0(t0)       // inptr[DCTSIZE*0]
-    mul         t7, s7, t7      // z3 = (inptr[DCTSIZE*6] * quantptr[DCTSIZE*6])
-    lh          s5, 0(a0)       // quantptr[0]
-    li          s6, 15137
-    li          s7, 6270
-    mul         t2, s4, s5      // tmp0 = (inptr[0] * quantptr[0])
-    mul         t6, s6, t6      // z2 = (inptr[DCTSIZE*2] * quantptr[DCTSIZE*2])
-    lh          t5, 112(t0)     // inptr[DCTSIZE*7]
-    mul         t7, s7, t7      // z3 = (inptr[DCTSIZE*6] * quantptr[DCTSIZE*6])
-    lh          s4, 112(a0)     // quantptr[DCTSIZE*7]
-    lh          v0, 80(t0)      // inptr[DCTSIZE*5]
-    lh          s5, 80(a0)      // quantptr[DCTSIZE*5]
-    lh          s6, 48(a0)      // quantptr[DCTSIZE*3]
-    sll         t2, t2, 14      // tmp0 <<= (CONST_BITS+1)
-    lh          s7, 16(a0)      // quantptr[DCTSIZE*1]
-    lh          t8, 16(t0)      // inptr[DCTSIZE*1]
-    subu        t6, t6, t7      // tmp2 = MULTIPLY(z2, t5) - MULTIPLY(z3, t6)
-    lh          t7, 48(t0)      // inptr[DCTSIZE*3]
-    mul         t5, s4, t5      // z1 = (inptr[DCTSIZE*7] * quantptr[DCTSIZE*7])
-    mul         v0, s5, v0      // z2 = (inptr[DCTSIZE*5] * quantptr[DCTSIZE*5])
-    mul         t7, s6, t7      // z3 = (inptr[DCTSIZE*3] * quantptr[DCTSIZE*3])
-    mul         t8, s7, t8      // z4 = (inptr[DCTSIZE*1] * quantptr[DCTSIZE*1])
-    addu        t3, t2, t6      // tmp10 = tmp0 + z2
-    subu        t4, t2, t6      // tmp10 = tmp0 - z2
-    mult        $ac0, zero, zero
-    mult        $ac1, zero, zero
-    ins         t5, v0, 16, 16
-    ins         t7, t8, 16, 16
-    addiu       t9, t9, -1
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    mflo        s4, $ac0
-    mflo        s5, $ac1
-    addiu       a0, a0, 2
-    addiu       t1, t1, 4
-    addiu       t0, t0, 2
-    addu        t6, t4, s4
-    subu        t5, t4, s4
-    addu        s6, t3, s5
-    subu        s7, t3, s5
-    shra_r.w    t6, t6, 12      // DESCALE(tmp12 + temp1, 12)
-    shra_r.w    t5, t5, 12      // DESCALE(tmp12 - temp1, 12)
-    shra_r.w    s6, s6, 12      // DESCALE(tmp10 + temp2, 12)
-    shra_r.w    s7, s7, 12      // DESCALE(tmp10 - temp2, 12)
-    sw          t6, 28(t1)
-    sw          t5, 60(t1)
-    sw          s6, -4(t1)
-    bgtz        t9, 0b
-     sw         s7, 92(t1)
-    // second loop three pass
-    li          t9, 3
-1:
-    lh          s6, 34(t0)      // inptr[DCTSIZE*2]
-    lh          t6, 34(a0)      // quantptr[DCTSIZE*2]
-    lh          s7, 98(t0)      // inptr[DCTSIZE*6]
-    lh          t7, 98(a0)      // quantptr[DCTSIZE*6]
-    mul         t6, s6, t6      // z2 = (inptr[DCTSIZE*2] * quantptr[DCTSIZE*2])
-    lh          s4, 2(t0)       // inptr[DCTSIZE*0]
-    mul         t7, s7, t7      // z3 = (inptr[DCTSIZE*6] * quantptr[DCTSIZE*6])
-    lh          s5, 2(a0)       // quantptr[DCTSIZE*0]
-    li          s6, 15137
-    li          s7, 6270
-    mul         t2, s4, s5      // tmp0 = (inptr[0] * quantptr[0])
-    mul         v0, s6, t6      // z2 = (inptr[DCTSIZE*2] * quantptr[DCTSIZE*2])
-    lh          t5, 114(t0)     // inptr[DCTSIZE*7]
-    mul         t7, s7, t7      // z3 = (inptr[DCTSIZE*6] * quantptr[DCTSIZE*6])
-    lh          s4, 114(a0)     // quantptr[DCTSIZE*7]
-    lh          s5, 82(a0)      // quantptr[DCTSIZE*5]
-    lh          t6, 82(t0)      // inptr[DCTSIZE*5]
-    sll         t2, t2, 14      // tmp0 <<= (CONST_BITS+1)
-    lh          s6, 50(a0)      // quantptr[DCTSIZE*3]
-    lh          t8, 18(t0)      // inptr[DCTSIZE*1]
-    subu        v0, v0, t7      // tmp2 = MULTIPLY(z2, t5) - MULTIPLY(z3, t6)
-    lh          t7, 50(t0)      // inptr[DCTSIZE*3]
-    lh          s7, 18(a0)      // quantptr[DCTSIZE*1]
-    mul         t5, s4, t5      // z1 = (inptr[DCTSIZE*7] * quantptr[DCTSIZE*7])
-    mul         t6, s5, t6      // z2 = (inptr[DCTSIZE*5] * quantptr[DCTSIZE*5])
-    mul         t7, s6, t7      // z3 = (inptr[DCTSIZE*3] * quantptr[DCTSIZE*3])
-    mul         t8, s7, t8      // z4 = (inptr[DCTSIZE*1] * quantptr[DCTSIZE*1])
-    addu        t3, t2, v0      // tmp10 = tmp0 + z2
-    subu        t4, t2, v0      // tmp10 = tmp0 - z2
-    mult        $ac0, zero, zero
-    mult        $ac1, zero, zero
-    ins         t5, t6, 16, 16
-    ins         t7, t8, 16, 16
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    mflo        t5, $ac0
-    mflo        t6, $ac1
-    addiu       t9, t9, -1
-    addiu       t0, t0, 2
-    addiu       a0, a0, 2
-    addiu       t1, t1, 4
-    addu        s5, t4, t5
-    subu        s4, t4, t5
-    addu        s6, t3, t6
-    subu        s7, t3, t6
-    shra_r.w    s5, s5, 12      // DESCALE(tmp12 + temp1, 12)
-    shra_r.w    s4, s4, 12      // DESCALE(tmp12 - temp1, 12)
-    shra_r.w    s6, s6, 12      // DESCALE(tmp10 + temp2, 12)
-    shra_r.w    s7, s7, 12      // DESCALE(tmp10 - temp2, 12)
-    sw          s5, 32(t1)
-    sw          s4, 64(t1)
-    sw          s6, 0(t1)
-    bgtz        t9, 1b
-     sw         s7, 96(t1)
-    move        t1, v1
-    li          s4, 15137
-    lw          s6, 8(t1)       // wsptr[2]
-    li          s5, 6270
-    lw          s7, 24(t1)      // wsptr[6]
-    mul         s4, s4, s6      // MULTIPLY((JLONG)wsptr[2], FIX_1_847759065)
-    lw          t2, 0(t1)       // wsptr[0]
-    mul         s5, s5, s7      // MULTIPLY((JLONG)wsptr[6], -FIX_0_765366865)
-    lh          t5, 28(t1)      // wsptr[7]
-    lh          t6, 20(t1)      // wsptr[5]
-    lh          t7, 12(t1)      // wsptr[3]
-    lh          t8, 4(t1)       // wsptr[1]
-    ins         t5, t6, 16, 16
-    ins         t7, t8, 16, 16
-    mult        $ac0, zero, zero
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    mult        $ac1, zero, zero
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    sll         t2, t2, 14      // tmp0 = ((JLONG)wsptr[0]) << (CONST_BITS+1)
-    mflo        s6, $ac0
-    // MULTIPLY(wsptr[2], FIX_1_847759065 + MULTIPLY(wsptr[6], -FIX_0_765366865)
-    subu        s4, s4, s5
-    addu        t3, t2, s4      // tmp10 = tmp0 + z2
-    mflo        s7, $ac1
-    subu        t4, t2, s4      // tmp10 = tmp0 - z2
-    addu        t7, t4, s6
-    subu        t8, t4, s6
-    addu        t5, t3, s7
-    subu        t6, t3, s7
-    shra_r.w    t5, t5, 19      // DESCALE(tmp10 + temp2, 19)
-    shra_r.w    t6, t6, 19      // DESCALE(tmp10 - temp2, 19)
-    shra_r.w    t7, t7, 19      // DESCALE(tmp12 + temp1, 19)
-    shra_r.w    t8, t8, 19      // DESCALE(tmp12 - temp1, 19)
-    sll         s4, t9, 2
-    lw          v0, 0(a2)       // output_buf[ctr]
-    shll_s.w    t5, t5, 24
-    shll_s.w    t6, t6, 24
-    shll_s.w    t7, t7, 24
-    shll_s.w    t8, t8, 24
-    sra         t5, t5, 24
-    sra         t6, t6, 24
-    sra         t7, t7, 24
-    sra         t8, t8, 24
-    addu        v0, v0, a3      // outptr = output_buf[ctr] + output_col
-    addiu       t5, t5, 128
-    addiu       t6, t6, 128
-    addiu       t7, t7, 128
-    addiu       t8, t8, 128
-    sb          t5, 0(v0)
-    sb          t7, 1(v0)
-    sb          t8, 2(v0)
-    sb          t6, 3(v0)
-    // 2
-    li          s4, 15137
-    lw          s6, 40(t1)      // wsptr[2]
-    li          s5, 6270
-    lw          s7, 56(t1)      // wsptr[6]
-    mul         s4, s4, s6      // MULTIPLY((JLONG)wsptr[2], FIX_1_847759065)
-    lw          t2, 32(t1)      // wsptr[0]
-    mul         s5, s5, s7      // MULTIPLY((JLONG)wsptr[6], -FIX_0_765366865)
-    lh          t5, 60(t1)      // wsptr[7]
-    lh          t6, 52(t1)      // wsptr[5]
-    lh          t7, 44(t1)      // wsptr[3]
-    lh          t8, 36(t1)      // wsptr[1]
-    ins         t5, t6, 16, 16
-    ins         t7, t8, 16, 16
-    mult        $ac0, zero, zero
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    mult        $ac1, zero, zero
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    sll         t2, t2, 14      // tmp0 = ((JLONG)wsptr[0]) << (CONST_BITS+1)
-    mflo        s6, $ac0
-    // MULTIPLY(wsptr[2], FIX_1_847759065 + MULTIPLY(wsptr[6], -FIX_0_765366865)
-    subu        s4, s4, s5
-    addu        t3, t2, s4      // tmp10 = tmp0 + z2
-    mflo        s7, $ac1
-    subu        t4, t2, s4      // tmp10 = tmp0 - z2
-    addu        t7, t4, s6
-    subu        t8, t4, s6
-    addu        t5, t3, s7
-    subu        t6, t3, s7
-    shra_r.w    t5, t5, 19      // DESCALE(tmp10 + temp2, CONST_BITS-PASS1_BITS+1)
-    shra_r.w    t6, t6, 19      // DESCALE(tmp10 - temp2, CONST_BITS-PASS1_BITS+1)
-    shra_r.w    t7, t7, 19      // DESCALE(tmp12 + temp1, CONST_BITS-PASS1_BITS+1)
-    shra_r.w    t8, t8, 19      // DESCALE(tmp12 - temp1, CONST_BITS-PASS1_BITS+1)
-    sll         s4, t9, 2
-    lw          v0, 4(a2)       // output_buf[ctr]
-    shll_s.w    t5, t5, 24
-    shll_s.w    t6, t6, 24
-    shll_s.w    t7, t7, 24
-    shll_s.w    t8, t8, 24
-    sra         t5, t5, 24
-    sra         t6, t6, 24
-    sra         t7, t7, 24
-    sra         t8, t8, 24
-    addu        v0, v0, a3      // outptr = output_buf[ctr] + output_col
-    addiu       t5, t5, 128
-    addiu       t6, t6, 128
-    addiu       t7, t7, 128
-    addiu       t8, t8, 128
-    sb          t5, 0(v0)
-    sb          t7, 1(v0)
-    sb          t8, 2(v0)
-    sb          t6, 3(v0)
-    // 3
-    li          s4, 15137
-    lw          s6, 72(t1)      // wsptr[2]
-    li          s5, 6270
-    lw          s7, 88(t1)      // wsptr[6]
-    mul         s4, s4, s6      // MULTIPLY((JLONG)wsptr[2], FIX_1_847759065)
-    lw          t2, 64(t1)      // wsptr[0]
-    mul         s5, s5, s7      // MULTIPLY((JLONG)wsptr[6], -FIX_0_765366865)
-    lh          t5, 92(t1)      // wsptr[7]
-    lh          t6, 84(t1)      // wsptr[5]
-    lh          t7, 76(t1)      // wsptr[3]
-    lh          t8, 68(t1)      // wsptr[1]
-    ins         t5, t6, 16, 16
-    ins         t7, t8, 16, 16
-    mult        $ac0, zero, zero
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    mult        $ac1, zero, zero
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    sll         t2, t2, 14      // tmp0 = ((JLONG)wsptr[0]) << (CONST_BITS+1)
-    mflo        s6, $ac0
-    // MULTIPLY(wsptr[2], FIX_1_847759065 + MULTIPLY(wsptr[6], -FIX_0_765366865)
-    subu        s4, s4, s5
-    addu        t3, t2, s4      // tmp10 = tmp0 + z2
-    mflo        s7, $ac1
-    subu        t4, t2, s4      // tmp10 = tmp0 - z2
-    addu        t7, t4, s6
-    subu        t8, t4, s6
-    addu        t5, t3, s7
-    subu        t6, t3, s7
-    shra_r.w    t5, t5, 19      // DESCALE(tmp10 + temp2, 19)
-    shra_r.w    t6, t6, 19      // DESCALE(tmp10 - temp2, 19)
-    shra_r.w    t7, t7, 19      // DESCALE(tmp12 + temp1, 19)
-    shra_r.w    t8, t8, 19      // DESCALE(tmp12 - temp1, 19)
-    sll         s4, t9, 2
-    lw          v0, 8(a2)       // output_buf[ctr]
-    shll_s.w    t5, t5, 24
-    shll_s.w    t6, t6, 24
-    shll_s.w    t7, t7, 24
-    shll_s.w    t8, t8, 24
-    sra         t5, t5, 24
-    sra         t6, t6, 24
-    sra         t7, t7, 24
-    sra         t8, t8, 24
-    addu        v0, v0, a3      // outptr = output_buf[ctr] + output_col
-    addiu       t5, t5, 128
-    addiu       t6, t6, 128
-    addiu       t7, t7, 128
-    addiu       t8, t8, 128
-    sb          t5, 0(v0)
-    sb          t7, 1(v0)
-    sb          t8, 2(v0)
-    sb          t6, 3(v0)
-    li          s4, 15137
-    lw          s6, 104(t1)     // wsptr[2]
-    li          s5, 6270
-    lw          s7, 120(t1)     // wsptr[6]
-    mul         s4, s4, s6      // MULTIPLY((JLONG)wsptr[2], FIX_1_847759065)
-    lw          t2, 96(t1)      // wsptr[0]
-    mul         s5, s5, s7      // MULTIPLY((JLONG)wsptr[6], -FIX_0_765366865)
-    lh          t5, 124(t1)     // wsptr[7]
-    lh          t6, 116(t1)     // wsptr[5]
-    lh          t7, 108(t1)     // wsptr[3]
-    lh          t8, 100(t1)     // wsptr[1]
-    ins         t5, t6, 16, 16
-    ins         t7, t8, 16, 16
-    mult        $ac0, zero, zero
-    dpa.w.ph    $ac0, t5, s0
-    dpa.w.ph    $ac0, t7, s1
-    mult        $ac1, zero, zero
-    dpa.w.ph    $ac1, t5, s2
-    dpa.w.ph    $ac1, t7, s3
-    sll         t2, t2, 14      // tmp0 = ((JLONG)wsptr[0]) << (CONST_BITS+1)
-    mflo        s6, $ac0
-    // MULTIPLY(wsptr[2], FIX_1_847759065 + MULTIPLY(wsptr[6], -FIX_0_765366865)
-    subu        s4, s4, s5
-    addu        t3, t2, s4      // tmp10 = tmp0 + z2;
-    mflo        s7, $ac1
-    subu        t4, t2, s4      // tmp10 = tmp0 - z2;
-    addu        t7, t4, s6
-    subu        t8, t4, s6
-    addu        t5, t3, s7
-    subu        t6, t3, s7
-    shra_r.w    t5, t5, 19      // DESCALE(tmp10 + temp2, 19)
-    shra_r.w    t6, t6, 19      // DESCALE(tmp10 - temp2, 19)
-    shra_r.w    t7, t7, 19      // DESCALE(tmp12 + temp1, 19)
-    shra_r.w    t8, t8, 19      // DESCALE(tmp12 - temp1, 19)
-    sll         s4, t9, 2
-    lw          v0, 12(a2)      // output_buf[ctr]
-    shll_s.w    t5, t5, 24
-    shll_s.w    t6, t6, 24
-    shll_s.w    t7, t7, 24
-    shll_s.w    t8, t8, 24
-    sra         t5, t5, 24
-    sra         t6, t6, 24
-    sra         t7, t7, 24
-    sra         t8, t8, 24
-    addu        v0, v0, a3      // outptr = output_buf[ctr] + output_col
-    addiu       t5, t5, 128
-    addiu       t6, t6, 128
-    addiu       t7, t7, 128
-    addiu       t8, t8, 128
-    sb          t5, 0(v0)
-    sb          t7, 1(v0)
-    sb          t8, 2(v0)
-    sb          t6, 3(v0)
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-END(jsimd_idct_4x4_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_6x6_dspr2)
-/*
- * a0 = compptr->dct_table
- * a1 = coef_block
- * a2 = output_buf
- * a3 = output_col
- */
-    .set at
-
-    SAVE_REGS_ON_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    addiu       sp, sp, -144
-    move        v0, sp
-    addiu       v1, v0, 24
-    addiu       t9, zero, 5793
-    addiu       s0, zero, 10033
-    addiu       s1, zero, 2998
-
-1:
-    lh          s2, 0(a0)       // q0 = quantptr[ 0]
-    lh          s3, 32(a0)      // q1 = quantptr[16]
-    lh          s4, 64(a0)      // q2 = quantptr[32]
-    lh          t2, 64(a1)      // tmp2 = inptr[32]
-    lh          t1, 32(a1)      // tmp1 = inptr[16]
-    lh          t0, 0(a1)       // tmp0 = inptr[ 0]
-    mul         t2, t2, s4      // tmp2 = tmp2 * q2
-    mul         t1, t1, s3      // tmp1 = tmp1 * q1
-    mul         t0, t0, s2      // tmp0 = tmp0 * q0
-    lh          t6, 16(a1)      // z1 = inptr[ 8]
-    lh          t8, 80(a1)      // z3 = inptr[40]
-    lh          t7, 48(a1)      // z2 = inptr[24]
-    lh          s2, 16(a0)      // q0 = quantptr[ 8]
-    lh          s4, 80(a0)      // q2 = quantptr[40]
-    lh          s3, 48(a0)      // q1 = quantptr[24]
-    mul         t2, t2, t9      // tmp2 = tmp2 * 5793
-    mul         t1, t1, s0      // tmp1 = tmp1 * 10033
-    sll         t0, t0, 13      // tmp0 = tmp0 << 13
-    mul         t6, t6, s2      // z1 = z1 * q0
-    mul         t8, t8, s4      // z3 = z3 * q2
-    mul         t7, t7, s3      // z2 = z2 * q1
-    addu        t3, t0, t2      // tmp10 = tmp0 + tmp2
-    sll         t2, t2, 1       // tmp2 = tmp2 << 2
-    subu        t4, t0, t2      // tmp11 = tmp0 - tmp2;
-    subu        t5, t3, t1      // tmp12 = tmp10 - tmp1
-    addu        t3, t3, t1      // tmp10 = tmp10 + tmp1
-    addu        t1, t6, t8      // tmp1 = z1 + z3
-    mul         t1, t1, s1      // tmp1 = tmp1 * 2998
-    shra_r.w    t4, t4, 11      // tmp11 = (tmp11 + 1024) >> 11
-    subu        t2, t6, t8      // tmp2 = z1 - z3
-    subu        t2, t2, t7      // tmp2 = tmp2 - z2
-    sll         t2, t2, 2       // tmp2 = tmp2 << 2
-    addu        t0, t6, t7      // tmp0 = z1 + z2
-    sll         t0, t0, 13      // tmp0 = tmp0 << 13
-    subu        s2, t8, t7      // q0 = z3 - z2
-    sll         s2, s2, 13      // q0 = q0 << 13
-    addu        t0, t0, t1      // tmp0 = tmp0 + tmp1
-    addu        t1, s2, t1      // tmp1 = q0 + tmp1
-    addu        s2, t4, t2      // q0 = tmp11 + tmp2
-    subu        s3, t4, t2      // q1 = tmp11 - tmp2
-    addu        t6, t3, t0      // z1 = tmp10 + tmp0
-    subu        t7, t3, t0      // z2 = tmp10 - tmp0
-    addu        t4, t5, t1      // tmp11 = tmp12 + tmp1
-    subu        t5, t5, t1      // tmp12 = tmp12 - tmp1
-    shra_r.w    t6, t6, 11      // z1 = (z1 + 1024) >> 11
-    shra_r.w    t7, t7, 11      // z2 = (z2 + 1024) >> 11
-    shra_r.w    t4, t4, 11      // tmp11 = (tmp11 + 1024) >> 11
-    shra_r.w    t5, t5, 11      // tmp12 = (tmp12 + 1024) >> 11
-    sw          s2, 24(v0)
-    sw          s3, 96(v0)
-    sw          t6, 0(v0)
-    sw          t7, 120(v0)
-    sw          t4, 48(v0)
-    sw          t5, 72(v0)
-    addiu       v0, v0, 4
-    addiu       a1, a1, 2
-    bne         v0, v1, 1b
-     addiu      a0, a0, 2
-
-    /* Pass 2: process 6 rows from work array, store into output array. */
-    move        v0, sp
-    addiu       v1, v0, 144
-
-2:
-    lw          t0, 0(v0)
-    lw          t2, 16(v0)
-    lw          s5, 0(a2)
-    addiu       t0, t0, 16
-    sll         t0, t0, 13
-    mul         t3, t2, t9
-    lw          t6, 4(v0)
-    lw          t8, 20(v0)
-    lw          t7, 12(v0)
-    addu        s5, s5, a3
-    addu        s6, t6, t8
-    mul         s6, s6, s1
-    addu        t1, t0, t3
-    subu        t4, t0, t3
-    subu        t4, t4, t3
-    lw          t3, 8(v0)
-    mul         t0, t3, s0
-    addu        s7, t6, t7
-    sll         s7, s7, 13
-    addu        s7, s6, s7
-    subu        t2, t8, t7
-    sll         t2, t2, 13
-    addu        t2, s6, t2
-    subu        s6, t6, t7
-    subu        s6, s6, t8
-    sll         s6, s6, 13
-    addu        t3, t1, t0
-    subu        t5, t1, t0
-    addu        t6, t3, s7
-    subu        t3, t3, s7
-    addu        t7, t4, s6
-    subu        t4, t4, s6
-    addu        t8, t5, t2
-    subu        t5, t5, t2
-    shll_s.w    t6, t6, 6
-    shll_s.w    t3, t3, 6
-    shll_s.w    t7, t7, 6
-    shll_s.w    t4, t4, 6
-    shll_s.w    t8, t8, 6
-    shll_s.w    t5, t5, 6
-    sra         t6, t6, 24
-    addiu       t6, t6, 128
-    sra         t3, t3, 24
-    addiu       t3, t3, 128
-    sb          t6, 0(s5)
-    sra         t7, t7, 24
-    addiu       t7, t7, 128
-    sb          t3, 5(s5)
-    sra         t4, t4, 24
-    addiu       t4, t4, 128
-    sb          t7, 1(s5)
-    sra         t8, t8, 24
-    addiu       t8, t8, 128
-    sb          t4, 4(s5)
-    addiu       v0, v0, 24
-    sra         t5, t5, 24
-    addiu       t5, t5, 128
-    sb          t8, 2(s5)
-    addiu       a2, a2,  4
-    bne         v0, v1, 2b
-     sb         t5, 3(s5)
-
-    addiu       sp, sp, 144
-
-    RESTORE_REGS_FROM_STACK 32, s0, s1, s2, s3, s4, s5, s6, s7
-
-    j           ra
-     nop
-
-END(jsimd_idct_6x6_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_12x12_pass1_dspr2)
-/*
- * a0 = compptr->dct_table
- * a1 = coef_block
- * a2 = workspace
- */
-    SAVE_REGS_ON_STACK 16, s0, s1, s2, s3
-
-    li          a3, 8
-
-1:
-    // odd part
-    lh          t0, 48(a1)
-    lh          t1, 48(a0)
-    lh          t2, 16(a1)
-    lh          t3, 16(a0)
-    lh          t4, 80(a1)
-    lh          t5, 80(a0)
-    lh          t6, 112(a1)
-    lh          t7, 112(a0)
-    mul         t0, t0, t1      // z2
-    mul         t1, t2, t3      // z1
-    mul         t2, t4, t5      // z3
-    mul         t3, t6, t7      // z4
-    li          t4, 10703       // FIX(1.306562965)
-    li          t5, 4433        // FIX_0_541196100
-    li          t6, 7053        // FIX(0.860918669)
-    mul         t4, t0, t4      // tmp11
-    mul         t5, t0, t5      // -tmp14
-    addu        t7, t1, t2      // tmp10
-    addu        t8, t7, t3      // tmp10 + z4
-    mul         t6, t6, t8      // tmp15
-    li          t8, 2139        // FIX(0.261052384)
-    mul         t8, t7, t8      // MULTIPLY(tmp10, FIX(0.261052384))
-    li          t7, 2295        // FIX(0.280143716)
-    mul         t7, t1, t7      // MULTIPLY(z1, FIX(0.280143716))
-    addu        t9, t2, t3      // z3 + z4
-    li          s0, 8565        // FIX(1.045510580)
-    mul         t9, t9, s0      // -tmp13
-    li          s0, 12112       // FIX(1.478575242)
-    mul         s0, t2, s0      // MULTIPLY(z3, FIX(1.478575242)
-    li          s1, 12998       // FIX(1.586706681)
-    mul         s1, t3, s1      // MULTIPLY(z4, FIX(1.586706681))
-    li          s2, 5540        // FIX(0.676326758)
-    mul         s2, t1, s2      // MULTIPLY(z1, FIX(0.676326758))
-    li          s3, 16244       // FIX(1.982889723)
-    mul         s3, t3, s3      // MULTIPLY(z4, FIX(1.982889723))
-    subu        t1, t1, t3      // z1-=z4
-    subu        t0, t0, t2      // z2-=z3
-    addu        t2, t0, t1      // z1+z2
-    li          t3, 4433        // FIX_0_541196100
-    mul         t2, t2, t3      // z3
-    li          t3, 6270        // FIX_0_765366865
-    mul         t1, t1, t3      // MULTIPLY(z1, FIX_0_765366865)
-    li          t3, 15137       // FIX_0_765366865
-    mul         t0, t0, t3      // MULTIPLY(z2, FIX_1_847759065)
-    addu        t8, t6, t8      // tmp12
-    addu        t3, t8, t4      // tmp12 + tmp11
-    addu        t3, t3, t7      // tmp10
-    subu        t8, t8, t9      // tmp12 + tmp13
-    addu        s0, t5, s0
-    subu        t8, t8, s0      // tmp12
-    subu        t9, t6, t9
-    subu        s1, s1, t4
-    addu        t9, t9, s1      // tmp13
-    subu        t6, t6, t5
-    subu        t6, t6, s2
-    subu        t6, t6, s3      // tmp15
-    // even part start
-    lh          t4, 64(a1)
-    lh          t5, 64(a0)
-    lh          t7, 32(a1)
-    lh          s0, 32(a0)
-    lh          s1, 0(a1)
-    lh          s2, 0(a0)
-    lh          s3, 96(a1)
-    lh          v0, 96(a0)
-    mul         t4, t4, t5      // DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4])
-    mul         t5, t7, s0      // DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2])
-    mul         t7, s1, s2      // DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0])
-    mul         s0, s3, v0      // DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6])
-    // odd part end
-    addu        t1, t2, t1      // tmp11
-    subu        t0, t2, t0      // tmp14
-    // update counter and pointers
-    addiu       a3, a3, -1
-    addiu       a0, a0, 2
-    addiu       a1, a1, 2
-    // even part rest
-    li          s1, 10033
-    li          s2, 11190
-    mul         t4, t4, s1      // z4
-    mul         s1, t5, s2      // z4
-    sll         t5, t5, 13      // z1
-    sll         t7, t7, 13
-    addiu       t7, t7, 1024    // z3
-    sll         s0, s0, 13      // z2
-    addu        s2, t7, t4      // tmp10
-    subu        t4, t7, t4      // tmp11
-    subu        s3, t5, s0      // tmp12
-    addu        t2, t7, s3      // tmp21
-    subu        s3, t7, s3      // tmp24
-    addu        t7, s1, s0      // tmp12
-    addu        v0, s2, t7      // tmp20
-    subu        s2, s2, t7      // tmp25
-    subu        s1, s1, t5      // z4 - z1
-    subu        s1, s1, s0      // tmp12
-    addu        s0, t4, s1      // tmp22
-    subu        t4, t4, s1      // tmp23
-    // final output stage
-    addu        t5, v0, t3
-    subu        v0, v0, t3
-    addu        t3, t2, t1
-    subu        t2, t2, t1
-    addu        t1, s0, t8
-    subu        s0, s0, t8
-    addu        t8, t4, t9
-    subu        t4, t4, t9
-    addu        t9, s3, t0
-    subu        s3, s3, t0
-    addu        t0, s2, t6
-    subu        s2, s2, t6
-    sra         t5, t5, 11
-    sra         t3, t3, 11
-    sra         t1, t1, 11
-    sra         t8, t8, 11
-    sra         t9, t9, 11
-    sra         t0, t0, 11
-    sra         s2, s2, 11
-    sra         s3, s3, 11
-    sra         t4, t4, 11
-    sra         s0, s0, 11
-    sra         t2, t2, 11
-    sra         v0, v0, 11
-    sw          t5, 0(a2)
-    sw          t3, 32(a2)
-    sw          t1, 64(a2)
-    sw          t8, 96(a2)
-    sw          t9, 128(a2)
-    sw          t0, 160(a2)
-    sw          s2, 192(a2)
-    sw          s3, 224(a2)
-    sw          t4, 256(a2)
-    sw          s0, 288(a2)
-    sw          t2, 320(a2)
-    sw          v0, 352(a2)
-    bgtz        a3, 1b
-     addiu      a2, a2, 4
-
-    RESTORE_REGS_FROM_STACK 16, s0, s1, s2, s3
-
-    j           ra
-     nop
-
-END(jsimd_idct_12x12_pass1_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_idct_12x12_pass2_dspr2)
-/*
- * a0 = workspace
- * a1 = output
- */
-    SAVE_REGS_ON_STACK 16, s0, s1, s2, s3
-
-    li          a3, 12
-
-1:
-    // Odd part
-    lw          t0, 12(a0)
-    lw          t1, 4(a0)
-    lw          t2, 20(a0)
-    lw          t3, 28(a0)
-    li          t4, 10703       // FIX(1.306562965)
-    li          t5, 4433        // FIX_0_541196100
-    mul         t4, t0, t4      // tmp11
-    mul         t5, t0, t5      // -tmp14
-    addu        t6, t1, t2      // tmp10
-    li          t7, 2139        // FIX(0.261052384)
-    mul         t7, t6, t7      // MULTIPLY(tmp10, FIX(0.261052384))
-    addu        t6, t6, t3      // tmp10 + z4
-    li          t8, 7053        // FIX(0.860918669)
-    mul         t6, t6, t8      // tmp15
-    li          t8, 2295        // FIX(0.280143716)
-    mul         t8, t1, t8      // MULTIPLY(z1, FIX(0.280143716))
-    addu        t9, t2, t3      // z3 + z4
-    li          s0, 8565        // FIX(1.045510580)
-    mul         t9, t9, s0      // -tmp13
-    li          s0, 12112       // FIX(1.478575242)
-    mul         s0, t2, s0      // MULTIPLY(z3, FIX(1.478575242))
-    li          s1, 12998       // FIX(1.586706681)
-    mul         s1, t3, s1      // MULTIPLY(z4, FIX(1.586706681))
-    li          s2, 5540        // FIX(0.676326758)
-    mul         s2, t1, s2      // MULTIPLY(z1, FIX(0.676326758))
-    li          s3, 16244       // FIX(1.982889723)
-    mul         s3, t3, s3      // MULTIPLY(z4, FIX(1.982889723))
-    subu        t1, t1, t3      // z1 -= z4
-    subu        t0, t0, t2      // z2 -= z3
-    addu        t2, t1, t0      // z1 + z2
-    li          t3, 4433        // FIX_0_541196100
-    mul         t2, t2, t3      // z3
-    li          t3, 6270        // FIX_0_765366865
-    mul         t1, t1, t3      // MULTIPLY(z1, FIX_0_765366865)
-    li          t3, 15137       // FIX_1_847759065
-    mul         t0, t0, t3      // MULTIPLY(z2, FIX_1_847759065)
-    addu        t3, t6, t7      // tmp12
-    addu        t7, t3, t4
-    addu        t7, t7, t8      // tmp10
-    subu        t3, t3, t9
-    subu        t3, t3, t5
-    subu        t3, t3, s0      // tmp12
-    subu        t9, t6, t9
-    subu        t9, t9, t4
-    addu        t9, t9, s1      // tmp13
-    subu        t6, t6, t5
-    subu        t6, t6, s2
-    subu        t6, t6, s3      // tmp15
-    addu        t1, t2, t1      // tmp11
-    subu        t0, t2, t0      // tmp14
-    // even part
-    lw          t2, 16(a0)      // z4
-    lw          t4, 8(a0)       // z1
-    lw          t5, 0(a0)       // z3
-    lw          t8, 24(a0)      // z2
-    li          s0, 10033       // FIX(1.224744871)
-    li          s1, 11190       // FIX(1.366025404)
-    mul         t2, t2, s0      // z4
-    mul         s0, t4, s1      // z4
-    addiu       t5, t5, 0x10
-    sll         t5, t5, 13      // z3
-    sll         t4, t4, 13      // z1
-    sll         t8, t8, 13      // z2
-    subu        s1, t4, t8      // tmp12
-    addu        s2, t5, t2      // tmp10
-    subu        t2, t5, t2      // tmp11
-    addu        s3, t5, s1      // tmp21
-    subu        s1, t5, s1      // tmp24
-    addu        t5, s0, t8      // tmp12
-    addu        v0, s2, t5      // tmp20
-    subu        t5, s2, t5      // tmp25
-    subu        t4, s0, t4
-    subu        t4, t4, t8      // tmp12
-    addu        t8, t2, t4      // tmp22
-    subu        t2, t2, t4      // tmp23
-    // increment counter and pointers
-    addiu       a3, a3, -1
-    addiu       a0, a0, 32
-    // Final stage
-    addu        t4, v0, t7
-    subu        v0, v0, t7
-    addu        t7, s3, t1
-    subu        s3, s3, t1
-    addu        t1, t8, t3
-    subu        t8, t8, t3
-    addu        t3, t2, t9
-    subu        t2, t2, t9
-    addu        t9, s1, t0
-    subu        s1, s1, t0
-    addu        t0, t5, t6
-    subu        t5, t5, t6
-    sll         t4, t4, 4
-    sll         t7, t7, 4
-    sll         t1, t1, 4
-    sll         t3, t3, 4
-    sll         t9, t9, 4
-    sll         t0, t0, 4
-    sll         t5, t5, 4
-    sll         s1, s1, 4
-    sll         t2, t2, 4
-    sll         t8, t8, 4
-    sll         s3, s3, 4
-    sll         v0, v0, 4
-    shll_s.w    t4, t4, 2
-    shll_s.w    t7, t7, 2
-    shll_s.w    t1, t1, 2
-    shll_s.w    t3, t3, 2
-    shll_s.w    t9, t9, 2
-    shll_s.w    t0, t0, 2
-    shll_s.w    t5, t5, 2
-    shll_s.w    s1, s1, 2
-    shll_s.w    t2, t2, 2
-    shll_s.w    t8, t8, 2
-    shll_s.w    s3, s3, 2
-    shll_s.w    v0, v0, 2
-    srl         t4, t4, 24
-    srl         t7, t7, 24
-    srl         t1, t1, 24
-    srl         t3, t3, 24
-    srl         t9, t9, 24
-    srl         t0, t0, 24
-    srl         t5, t5, 24
-    srl         s1, s1, 24
-    srl         t2, t2, 24
-    srl         t8, t8, 24
-    srl         s3, s3, 24
-    srl         v0, v0, 24
-    lw          t6, 0(a1)
-    addiu       t4, t4, 0x80
-    addiu       t7, t7, 0x80
-    addiu       t1, t1, 0x80
-    addiu       t3, t3, 0x80
-    addiu       t9, t9, 0x80
-    addiu       t0, t0, 0x80
-    addiu       t5, t5, 0x80
-    addiu       s1, s1, 0x80
-    addiu       t2, t2, 0x80
-    addiu       t8, t8, 0x80
-    addiu       s3, s3, 0x80
-    addiu       v0, v0, 0x80
-    sb          t4, 0(t6)
-    sb          t7, 1(t6)
-    sb          t1, 2(t6)
-    sb          t3, 3(t6)
-    sb          t9, 4(t6)
-    sb          t0, 5(t6)
-    sb          t5, 6(t6)
-    sb          s1, 7(t6)
-    sb          t2, 8(t6)
-    sb          t8, 9(t6)
-    sb          s3, 10(t6)
-    sb          v0, 11(t6)
-    bgtz        a3, 1b
-     addiu      a1, a1, 4
-
-    RESTORE_REGS_FROM_STACK 16, s0, s1, s2, s3
-
-    jr          ra
-     nop
-
-END(jsimd_idct_12x12_pass2_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_convsamp_dspr2)
-/*
- * a0 = sample_data
- * a1 = start_col
- * a2 = workspace
- */
-    lw            t0, 0(a0)
-    li            t7, 0xff80ff80
-    addu          t0, t0, a1
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    lw            t0, 4(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 0(a2)
-    usw           t4, 4(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 8(a2)
-    usw           t6, 12(a2)
-
-    lw            t0, 8(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 16(a2)
-    usw           t4, 20(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 24(a2)
-    usw           t6, 28(a2)
-
-    lw            t0, 12(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 32(a2)
-    usw           t4, 36(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 40(a2)
-    usw           t6, 44(a2)
-
-    lw            t0, 16(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 48(a2)
-    usw           t4, 52(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 56(a2)
-    usw           t6, 60(a2)
-
-    lw            t0, 20(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 64(a2)
-    usw           t4, 68(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 72(a2)
-    usw           t6, 76(a2)
-
-    lw            t0, 24(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 80(a2)
-    usw           t4, 84(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 88(a2)
-    usw           t6, 92(a2)
-
-    lw            t0, 28(a0)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu          t0, t0, a1
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    ulw           t1, 0(t0)
-    ulw           t2, 4(t0)
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 96(a2)
-    usw           t4, 100(a2)
-    preceu.ph.qbr t3, t1
-    preceu.ph.qbl t4, t1
-    usw           t5, 104(a2)
-    usw           t6, 108(a2)
-    preceu.ph.qbr t5, t2
-    preceu.ph.qbl t6, t2
-    addu.ph       t3, t3, t7
-    addu.ph       t4, t4, t7
-    addu.ph       t5, t5, t7
-    addu.ph       t6, t6, t7
-    usw           t3, 112(a2)
-    usw           t4, 116(a2)
-    usw           t5, 120(a2)
-    usw           t6, 124(a2)
-
-    j             ra
-     nop
-
-END(jsimd_convsamp_dspr2)
-
-
-/*****************************************************************************/
-LEAF_DSPR2(jsimd_convsamp_float_dspr2)
-/*
- * a0 = sample_data
- * a1 = start_col
- * a2 = workspace
- */
-    .set at
-
-    lw          t0, 0(a0)
-    addu        t0, t0, a1
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 4(a0)
-    swc1        f2, 0(a2)
-    swc1        f4, 4(a2)
-    swc1        f6, 8(a2)
-    addu        t0, t0, a1
-    swc1        f8, 12(a2)
-    swc1        f10, 16(a2)
-    swc1        f12, 20(a2)
-    swc1        f14, 24(a2)
-    swc1        f16, 28(a2)
-    // elemr 1
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 8(a0)
-    swc1        f2, 32(a2)
-    swc1        f4, 36(a2)
-    swc1        f6, 40(a2)
-    addu        t0, t0, a1
-    swc1        f8, 44(a2)
-    swc1        f10, 48(a2)
-    swc1        f12, 52(a2)
-    swc1        f14, 56(a2)
-    swc1        f16, 60(a2)
-    // elemr 2
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 12(a0)
-    swc1        f2, 64(a2)
-    swc1        f4, 68(a2)
-    swc1        f6, 72(a2)
-    addu        t0, t0, a1
-    swc1        f8, 76(a2)
-    swc1        f10, 80(a2)
-    swc1        f12, 84(a2)
-    swc1        f14, 88(a2)
-    swc1        f16, 92(a2)
-    //  elemr 3
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 16(a0)
-    swc1        f2, 96(a2)
-    swc1        f4, 100(a2)
-    swc1        f6, 104(a2)
-    addu        t0, t0, a1
-    swc1        f8, 108(a2)
-    swc1        f10, 112(a2)
-    swc1        f12, 116(a2)
-    swc1        f14, 120(a2)
-    swc1        f16, 124(a2)
-    // elemr 4
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 20(a0)
-    swc1        f2, 128(a2)
-    swc1        f4, 132(a2)
-    swc1        f6, 136(a2)
-    addu        t0, t0, a1
-    swc1        f8, 140(a2)
-    swc1        f10, 144(a2)
-    swc1        f12, 148(a2)
-    swc1        f14, 152(a2)
-    swc1        f16, 156(a2)
-    // elemr 5
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 24(a0)
-    swc1        f2, 160(a2)
-    swc1        f4, 164(a2)
-    swc1        f6, 168(a2)
-    addu        t0, t0, a1
-    swc1        f8, 172(a2)
-    swc1        f10, 176(a2)
-    swc1        f12, 180(a2)
-    swc1        f14, 184(a2)
-    swc1        f16, 188(a2)
-    // elemr 6
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    lw          t0, 28(a0)
-    swc1        f2, 192(a2)
-    swc1        f4, 196(a2)
-    swc1        f6, 200(a2)
-    addu        t0, t0, a1
-    swc1        f8, 204(a2)
-    swc1        f10, 208(a2)
-    swc1        f12, 212(a2)
-    swc1        f14, 216(a2)
-    swc1        f16, 220(a2)
-    // elemr 7
-    lbu         t1, 0(t0)
-    lbu         t2, 1(t0)
-    lbu         t3, 2(t0)
-    lbu         t4, 3(t0)
-    lbu         t5, 4(t0)
-    lbu         t6, 5(t0)
-    lbu         t7, 6(t0)
-    lbu         t8, 7(t0)
-    addiu       t1, t1, -128
-    addiu       t2, t2, -128
-    addiu       t3, t3, -128
-    addiu       t4, t4, -128
-    addiu       t5, t5, -128
-    addiu       t6, t6, -128
-    addiu       t7, t7, -128
-    addiu       t8, t8, -128
-    mtc1        t1, f2
-    mtc1        t2, f4
-    mtc1        t3, f6
-    mtc1        t4, f8
-    mtc1        t5, f10
-    mtc1        t6, f12
-    mtc1        t7, f14
-    mtc1        t8, f16
-    cvt.s.w     f2, f2
-    cvt.s.w     f4, f4
-    cvt.s.w     f6, f6
-    cvt.s.w     f8, f8
-    cvt.s.w     f10, f10
-    cvt.s.w     f12, f12
-    cvt.s.w     f14, f14
-    cvt.s.w     f16, f16
-    swc1        f2, 224(a2)
-    swc1        f4, 228(a2)
-    swc1        f6, 232(a2)
-    swc1        f8, 236(a2)
-    swc1        f10, 240(a2)
-    swc1        f12, 244(a2)
-    swc1        f14, 248(a2)
-    swc1        f16, 252(a2)
-
-    j           ra
-     nop
-
-END(jsimd_convsamp_float_dspr2)
-
-/*****************************************************************************/
diff --git a/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2_asm.h b/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2_asm.h
deleted file mode 100644
index 12cfda4..0000000
--- a/src/third_party/libjpeg-turbo/simd/mips/jsimd_dspr2_asm.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * MIPS DSPr2 optimizations for libjpeg-turbo
- *
- * Copyright (C) 2013, MIPS Technologies, Inc., California.
- * Copyright (C) 2018, Matthieu Darbois.
- * All Rights Reserved.
- * Authors:  Teodora Novkovic (teodora.novkovic@imgtec.com)
- *           Darko Laus       (darko.laus@imgtec.com)
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#define zero  $0
-#define AT    $1
-#define v0    $2
-#define v1    $3
-#define a0    $4
-#define a1    $5
-#define a2    $6
-#define a3    $7
-#define t0    $8
-#define t1    $9
-#define t2    $10
-#define t3    $11
-#define t4    $12
-#define t5    $13
-#define t6    $14
-#define t7    $15
-#define s0    $16
-#define s1    $17
-#define s2    $18
-#define s3    $19
-#define s4    $20
-#define s5    $21
-#define s6    $22
-#define s7    $23
-#define t8    $24
-#define t9    $25
-#define k0    $26
-#define k1    $27
-#define gp    $28
-#define sp    $29
-#define fp    $30
-#define s8    $30
-#define ra    $31
-
-#define f0    $f0
-#define f1    $f1
-#define f2    $f2
-#define f3    $f3
-#define f4    $f4
-#define f5    $f5
-#define f6    $f6
-#define f7    $f7
-#define f8    $f8
-#define f9    $f9
-#define f10   $f10
-#define f11   $f11
-#define f12   $f12
-#define f13   $f13
-#define f14   $f14
-#define f15   $f15
-#define f16   $f16
-#define f17   $f17
-#define f18   $f18
-#define f19   $f19
-#define f20   $f20
-#define f21   $f21
-#define f22   $f22
-#define f23   $f23
-#define f24   $f24
-#define f25   $f25
-#define f26   $f26
-#define f27   $f27
-#define f28   $f28
-#define f29   $f29
-#define f30   $f30
-#define f31   $f31
-
-#ifdef __ELF__
-#define HIDDEN_SYMBOL(symbol)  .hidden symbol;
-#else
-#define HIDDEN_SYMBOL(symbol)
-#endif
-
-/*
- * LEAF_MIPS32R2 - declare leaf routine for MIPS32r2
- */
-#define LEAF_MIPS32R2(symbol) \
-    .globl      symbol; \
-    HIDDEN_SYMBOL(symbol) \
-    .align      2; \
-    .type       symbol, @function; \
-    .ent        symbol, 0; \
-symbol: \
-    .frame      sp, 0, ra; \
-    .set        push; \
-    .set        arch = mips32r2; \
-    .set        noreorder; \
-    .set        noat;
-
-/*
- * LEAF_DSPR2 - declare leaf routine for MIPS DSPr2
- */
-#define LEAF_DSPR2(symbol) \
-LEAF_MIPS32R2(symbol) \
-    .set        dspr2;
-
-/*
- * END - mark end of function
- */
-#define END(function) \
-    .set        pop; \
-    .end        function; \
-    .size       function, .-function
-
-/*
- * Checks if stack offset is big enough for storing/restoring regs_num
- * number of register to/from stack. Stack offset must be greater than
- * or equal to the number of bytes needed for storing registers (regs_num*4).
- * Since MIPS ABI allows usage of first 16 bytes of stack frame (this is
- * preserved for input arguments of the functions, already stored in a0-a3),
- * stack size can be further optimized by utilizing this space.
- */
-.macro CHECK_STACK_OFFSET regs_num, stack_offset
-.if \stack_offset < \regs_num * 4 - 16
-.error "Stack offset too small."
-.endif
-.endm
-
-/*
- * Saves set of registers on stack. Maximum number of registers that
- * can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
- * Stack offset is number of bytes that are added to stack pointer (sp)
- * before registers are pushed in order to provide enough space on stack
- * (offset must be multiple of 4, and must be big enough, as described by
- * CHECK_STACK_OFFSET macro). This macro is intended to be used in
- * combination with RESTORE_REGS_FROM_STACK macro. Example:
- *  SAVE_REGS_ON_STACK      4, v0, v1, s0, s1
- *  RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
- */
-.macro SAVE_REGS_ON_STACK  stack_offset = 0, r1, \
-                           r2  = 0, r3  = 0, r4  = 0, \
-                           r5  = 0, r6  = 0, r7  = 0, \
-                           r8  = 0, r9  = 0, r10 = 0, \
-                           r11 = 0, r12 = 0, r13 = 0, \
-                           r14 = 0
-.if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
-    .error "Stack offset must be pozitive and multiple of 4."
-.endif
-.if \stack_offset != 0
-    addiu       sp, sp, -\stack_offset
-.endif
-    sw          \r1, 0(sp)
-.if \r2 != 0
-    sw          \r2, 4(sp)
-.endif
-.if \r3 != 0
-    sw          \r3, 8(sp)
-.endif
-.if \r4 != 0
-    sw          \r4, 12(sp)
-.endif
-.if \r5 != 0
-    CHECK_STACK_OFFSET 5, \stack_offset
-    sw          \r5, 16(sp)
-.endif
-.if \r6 != 0
-    CHECK_STACK_OFFSET 6, \stack_offset
-    sw          \r6, 20(sp)
-.endif
-.if \r7 != 0
-    CHECK_STACK_OFFSET 7, \stack_offset
-    sw          \r7, 24(sp)
-.endif
-.if \r8 != 0
-    CHECK_STACK_OFFSET 8, \stack_offset
-    sw          \r8, 28(sp)
-.endif
-.if \r9 != 0
-    CHECK_STACK_OFFSET 9, \stack_offset
-    sw          \r9, 32(sp)
-.endif
-.if \r10 != 0
-    CHECK_STACK_OFFSET 10, \stack_offset
-    sw          \r10, 36(sp)
-.endif
-.if \r11 != 0
-    CHECK_STACK_OFFSET 11, \stack_offset
-    sw          \r11, 40(sp)
-.endif
-.if \r12 != 0
-    CHECK_STACK_OFFSET 12, \stack_offset
-    sw          \r12, 44(sp)
-.endif
-.if \r13 != 0
-    CHECK_STACK_OFFSET 13, \stack_offset
-    sw          \r13, 48(sp)
-.endif
-.if \r14 != 0
-    CHECK_STACK_OFFSET 14, \stack_offset
-    sw          \r14, 52(sp)
-.endif
-.endm
-
-/*
- * Restores set of registers from stack. Maximum number of registers that
- * can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
- * Stack offset is number of bytes that are added to stack pointer (sp)
- * after registers are restored (offset must be multiple of 4, and must
- * be big enough, as described by CHECK_STACK_OFFSET macro). This macro is
- * intended to be used in combination with RESTORE_REGS_FROM_STACK macro.
- * Example:
- *  SAVE_REGS_ON_STACK      4, v0, v1, s0, s1
- *  RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
- */
-.macro RESTORE_REGS_FROM_STACK  stack_offset = 0, r1, \
-                                r2  = 0, r3  = 0, r4  = 0, \
-                                r5  = 0, r6  = 0, r7  = 0, \
-                                r8  = 0, r9  = 0, r10 = 0, \
-                                r11 = 0, r12 = 0, r13 = 0, \
-                                r14 = 0
-.if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
-    .error "Stack offset must be pozitive and multiple of 4."
-.endif
-    lw          \r1, 0(sp)
-.if \r2 != 0
-    lw          \r2, 4(sp)
-.endif
-.if \r3 != 0
-    lw          \r3, 8(sp)
-.endif
-.if \r4 != 0
-    lw          \r4, 12(sp)
-.endif
-.if \r5 != 0
-    CHECK_STACK_OFFSET 5, \stack_offset
-    lw          \r5, 16(sp)
-.endif
-.if \r6 != 0
-    CHECK_STACK_OFFSET 6, \stack_offset
-    lw          \r6, 20(sp)
-.endif
-.if \r7 != 0
-    CHECK_STACK_OFFSET 7, \stack_offset
-    lw          \r7, 24(sp)
-.endif
-.if \r8 != 0
-    CHECK_STACK_OFFSET 8, \stack_offset
-    lw          \r8, 28(sp)
-.endif
-.if \r9 != 0
-    CHECK_STACK_OFFSET 9, \stack_offset
-    lw          \r9, 32(sp)
-.endif
-.if \r10 != 0
-    CHECK_STACK_OFFSET 10, \stack_offset
-    lw          \r10, 36(sp)
-.endif
-.if \r11 != 0
-    CHECK_STACK_OFFSET 11, \stack_offset
-    lw          \r11, 40(sp)
-.endif
-.if \r12 != 0
-    CHECK_STACK_OFFSET 12, \stack_offset
-    lw          \r12, 44(sp)
-.endif
-.if \r13 != 0
-    CHECK_STACK_OFFSET 13, \stack_offset
-    lw          \r13, 48(sp)
-.endif
-.if \r14 != 0
-    CHECK_STACK_OFFSET 14, \stack_offset
-    lw          \r14, 52(sp)
-.endif
-.if \stack_offset != 0
-    addiu       sp, sp, \stack_offset
-.endif
-.endm
diff --git a/src/third_party/libjpeg-turbo/simd/nasm/jcolsamp.inc b/src/third_party/libjpeg-turbo/simd/nasm/jcolsamp.inc
index a2d5b49..6f6d7f2 100644
--- a/src/third_party/libjpeg-turbo/simd/nasm/jcolsamp.inc
+++ b/src/third_party/libjpeg-turbo/simd/nasm/jcolsamp.inc
@@ -7,8 +7,6 @@
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
 ; For conditions of distribution and use, see copyright notice in jsimdext.inc
-;
-; [TAB8]
 
 ; --------------------------------------------------------------------------
 
diff --git a/src/third_party/libjpeg-turbo/simd/nasm/jdct.inc b/src/third_party/libjpeg-turbo/simd/nasm/jdct.inc
index 79d5146..9192f66 100644
--- a/src/third_party/libjpeg-turbo/simd/nasm/jdct.inc
+++ b/src/third_party/libjpeg-turbo/simd/nasm/jdct.inc
@@ -7,8 +7,6 @@
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
 ; For conditions of distribution and use, see copyright notice in jsimdext.inc
-;
-; [TAB8]
 
 ; Each IDCT routine is responsible for range-limiting its results and
 ; converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
diff --git a/src/third_party/libjpeg-turbo/simd/nasm/jsimdcfg.inc.h b/src/third_party/libjpeg-turbo/simd/nasm/jsimdcfg.inc.h
index 7ff7e29..bf2a45ad5 100644
--- a/src/third_party/libjpeg-turbo/simd/nasm/jsimdcfg.inc.h
+++ b/src/third_party/libjpeg-turbo/simd/nasm/jsimdcfg.inc.h
@@ -1,8 +1,10 @@
-// This file generates the include file for the assembly
-// implementations by abusing the C preprocessor.
-//
-// Note: Some things are manually defined as they need to
-// be mapped to NASM types.
+/*
+ * This file generates the include file for the assembly
+ * implementations by abusing the C preprocessor.
+ *
+ * Note: Some things are manually defined as they need to
+ * be mapped to NASM types.
+ */
 
 ;
 ; Automatically generated include file from jsimdcfg.inc.h
diff --git a/src/third_party/libjpeg-turbo/simd/nasm/jsimdext.inc b/src/third_party/libjpeg-turbo/simd/nasm/jsimdext.inc
index b40901f..e8d50b0 100644
--- a/src/third_party/libjpeg-turbo/simd/nasm/jsimdext.inc
+++ b/src/third_party/libjpeg-turbo/simd/nasm/jsimdext.inc
@@ -2,8 +2,9 @@
 ; jsimdext.inc - common declarations
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2010, 2016, D. R. Commander.
+; Copyright (C) 2010, 2016, 2018-2019, D. R. Commander.
 ; Copyright (C) 2018, Matthieu Darbois.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library - version 1.02
 ;
@@ -24,8 +25,6 @@
 ; 2. Altered source versions must be plainly marked as such, and must not be
 ;    misrepresented as being the original software.
 ; 3. This notice may not be removed or altered from any source distribution.
-;
-; [TAB8]
 
 ; ==========================================================================
 ;  System-dependent configurations
@@ -132,13 +131,53 @@
 ;  Common types
 ;
 %ifdef __x86_64__
+%ifnidn __OUTPUT_FORMAT__, elfx32
 %define POINTER         qword           ; general pointer type
 %define SIZEOF_POINTER  SIZEOF_QWORD    ; sizeof(POINTER)
 %define POINTER_BIT     QWORD_BIT       ; sizeof(POINTER)*BYTE_BIT
-%else
+%define resp            resq
+%define dp              dq
+%define raxp            rax
+%define rbxp            rbx
+%define rcxp            rcx
+%define rdxp            rdx
+%define rsip            rsi
+%define rdip            rdi
+%define rbpp            rbp
+%define rspp            rsp
+%define r8p             r8
+%define r9p             r9
+%define r10p            r10
+%define r11p            r11
+%define r12p            r12
+%define r13p            r13
+%define r14p            r14
+%define r15p            r15
+%endif
+%endif
+%ifndef raxp
 %define POINTER         dword           ; general pointer type
 %define SIZEOF_POINTER  SIZEOF_DWORD    ; sizeof(POINTER)
 %define POINTER_BIT     DWORD_BIT       ; sizeof(POINTER)*BYTE_BIT
+%define resp            resd
+%define dp              dd
+; x86_64 ILP32 ABI (x32)
+%define raxp            eax
+%define rbxp            ebx
+%define rcxp            ecx
+%define rdxp            edx
+%define rsip            esi
+%define rdip            edi
+%define rbpp            ebp
+%define rspp            esp
+%define r8p             r8d
+%define r9p             r9d
+%define r10p            r10d
+%define r11p            r11d
+%define r12p            r12d
+%define r13p            r13d
+%define r14p            r14d
+%define r15p            r15d
 %endif
 
 %define INT             dword           ; signed integer type
@@ -167,19 +206,19 @@
 %define XMM_DWORD
 %define XMM_MMWORD
 
-%define SIZEOF_BYTE   1                 ; sizeof(BYTE)
-%define SIZEOF_WORD   2                 ; sizeof(WORD)
-%define SIZEOF_DWORD  4                 ; sizeof(DWORD)
-%define SIZEOF_QWORD  8                 ; sizeof(QWORD)
-%define SIZEOF_OWORD  16                ; sizeof(OWORD)
-%define SIZEOF_YWORD  32                ; sizeof(YWORD)
+%define SIZEOF_BYTE   1                 ; sizeof(byte)
+%define SIZEOF_WORD   2                 ; sizeof(word)
+%define SIZEOF_DWORD  4                 ; sizeof(dword)
+%define SIZEOF_QWORD  8                 ; sizeof(qword)
+%define SIZEOF_OWORD  16                ; sizeof(oword)
+%define SIZEOF_YWORD  32                ; sizeof(yword)
 
 %define BYTE_BIT      8                 ; CHAR_BIT in C
-%define WORD_BIT      16                ; sizeof(WORD)*BYTE_BIT
-%define DWORD_BIT     32                ; sizeof(DWORD)*BYTE_BIT
-%define QWORD_BIT     64                ; sizeof(QWORD)*BYTE_BIT
-%define OWORD_BIT     128               ; sizeof(OWORD)*BYTE_BIT
-%define YWORD_BIT     256               ; sizeof(YWORD)*BYTE_BIT
+%define WORD_BIT      16                ; sizeof(word)*BYTE_BIT
+%define DWORD_BIT     32                ; sizeof(dword)*BYTE_BIT
+%define QWORD_BIT     64                ; sizeof(qword)*BYTE_BIT
+%define OWORD_BIT     128               ; sizeof(oword)*BYTE_BIT
+%define YWORD_BIT     256               ; sizeof(yword)*BYTE_BIT
 
 ; --------------------------------------------------------------------------
 ;  External Symbol Name
@@ -198,6 +237,11 @@
 %ifdef __YASM_VER__
 %define GLOBAL_FUNCTION(name)  global EXTN(name):private_extern
 %define GLOBAL_DATA(name)      global EXTN(name):private_extern
+%else
+%if __NASM_VERSION_ID__ >= 0x020E0000
+%define GLOBAL_FUNCTION(name)  global EXTN(name):private_extern
+%define GLOBAL_DATA(name)      global EXTN(name):private_extern
+%endif
 %endif
 %endif
 
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jccolext-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jccolext-altivec.c
deleted file mode 100644
index 170f90f..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jccolext-altivec.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2014, Jay Foad.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jccolor-altivec.c */
-
-
-void jsimd_rgb_ycc_convert_altivec(JDIMENSION img_width, JSAMPARRAY input_buf,
-                                   JSAMPIMAGE output_buf,
-                                   JDIMENSION output_row, int num_rows)
-{
-  JSAMPROW inptr, outptr0, outptr1, outptr2;
-  int pitch = img_width * RGB_PIXELSIZE, num_cols;
-#if __BIG_ENDIAN__
-  int offset;
-#endif
-  unsigned char __attribute__((aligned(16))) tmpbuf[RGB_PIXELSIZE * 16];
-
-  __vector unsigned char rgb0, rgb1 = { 0 }, rgb2 = { 0 },
-    rgbg0, rgbg1, rgbg2, rgbg3, y, cb, cr;
-#if __BIG_ENDIAN__ || RGB_PIXELSIZE == 4
-  __vector unsigned char rgb3 = { 0 };
-#endif
-#if __BIG_ENDIAN__ && RGB_PIXELSIZE == 4
-  __vector unsigned char rgb4 = { 0 };
-#endif
-  __vector short rg0, rg1, rg2, rg3, bg0, bg1, bg2, bg3;
-  __vector unsigned short yl, yh, crl, crh, cbl, cbh;
-  __vector int y0, y1, y2, y3, cr0, cr1, cr2, cr3, cb0, cb1, cb2, cb3;
-
-  /* Constants */
-  __vector short pw_f0299_f0337 = { __4X2(F_0_299, F_0_337) },
-    pw_f0114_f0250 = { __4X2(F_0_114, F_0_250) },
-    pw_mf016_mf033 = { __4X2(-F_0_168, -F_0_331) },
-    pw_mf008_mf041 = { __4X2(-F_0_081, -F_0_418) };
-  __vector unsigned short pw_f050_f000 = { __4X2(F_0_500, 0) };
-  __vector int pd_onehalf = { __4X(ONE_HALF) },
-    pd_onehalfm1_cj = { __4X(ONE_HALF - 1 + (CENTERJSAMPLE << SCALEBITS)) };
-  __vector unsigned char pb_zero = { __16X(0) },
-#if __BIG_ENDIAN__
-    shift_pack_index =
-      {  0,  1,  4,  5,  8,  9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 };
-#else
-    shift_pack_index =
-      {  2,  3,  6,  7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 };
-#endif
-
-  while (--num_rows >= 0) {
-    inptr = *input_buf++;
-    outptr0 = output_buf[0][output_row];
-    outptr1 = output_buf[1][output_row];
-    outptr2 = output_buf[2][output_row];
-    output_row++;
-
-    for (num_cols = pitch; num_cols > 0;
-         num_cols -= RGB_PIXELSIZE * 16, inptr += RGB_PIXELSIZE * 16,
-         outptr0 += 16, outptr1 += 16, outptr2 += 16) {
-
-#if __BIG_ENDIAN__
-      /* Load 16 pixels == 48 or 64 bytes */
-      offset = (size_t)inptr & 15;
-      if (offset) {
-        __vector unsigned char unaligned_shift_index;
-        int bytes = num_cols + offset;
-
-        if (bytes < (RGB_PIXELSIZE + 1) * 16 && (bytes & 15)) {
-          /* Slow path to prevent buffer overread.  Since there is no way to
-           * read a partial AltiVec register, overread would occur on the last
-           * chunk of the last image row if the right edge is not on a 16-byte
-           * boundary.  It could also occur on other rows if the bytes per row
-           * is low enough.  Since we can't determine whether we're on the last
-           * image row, we have to assume every row is the last.
-           */
-          memcpy(tmpbuf, inptr, min(num_cols, RGB_PIXELSIZE * 16));
-          rgb0 = vec_ld(0, tmpbuf);
-          rgb1 = vec_ld(16, tmpbuf);
-          rgb2 = vec_ld(32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          rgb3 = vec_ld(48, tmpbuf);
-#endif
-        } else {
-          /* Fast path */
-          rgb0 = vec_ld(0, inptr);
-          if (bytes > 16)
-            rgb1 = vec_ld(16, inptr);
-          if (bytes > 32)
-            rgb2 = vec_ld(32, inptr);
-          if (bytes > 48)
-            rgb3 = vec_ld(48, inptr);
-#if RGB_PIXELSIZE == 4
-          if (bytes > 64)
-            rgb4 = vec_ld(64, inptr);
-#endif
-          unaligned_shift_index = vec_lvsl(0, inptr);
-          rgb0 = vec_perm(rgb0, rgb1, unaligned_shift_index);
-          rgb1 = vec_perm(rgb1, rgb2, unaligned_shift_index);
-          rgb2 = vec_perm(rgb2, rgb3, unaligned_shift_index);
-#if RGB_PIXELSIZE == 4
-          rgb3 = vec_perm(rgb3, rgb4, unaligned_shift_index);
-#endif
-        }
-      } else {
-#endif /* __BIG_ENDIAN__ */
-        if (num_cols < RGB_PIXELSIZE * 16 && (num_cols & 15)) {
-          /* Slow path */
-          memcpy(tmpbuf, inptr, min(num_cols, RGB_PIXELSIZE * 16));
-          rgb0 = VEC_LD(0, tmpbuf);
-          rgb1 = VEC_LD(16, tmpbuf);
-          rgb2 = VEC_LD(32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          rgb3 = VEC_LD(48, tmpbuf);
-#endif
-        } else {
-          /* Fast path */
-          rgb0 = VEC_LD(0, inptr);
-          if (num_cols > 16)
-            rgb1 = VEC_LD(16, inptr);
-          if (num_cols > 32)
-            rgb2 = VEC_LD(32, inptr);
-#if RGB_PIXELSIZE == 4
-          if (num_cols > 48)
-            rgb3 = VEC_LD(48, inptr);
-#endif
-        }
-#if __BIG_ENDIAN__
-      }
-#endif
-
-#if RGB_PIXELSIZE == 3
-      /* rgb0 = R0 G0 B0 R1 G1 B1 R2 G2 B2 R3 G3 B3 R4 G4 B4 R5
-       * rgb1 = G5 B5 R6 G6 B6 R7 G7 B7 R8 G8 B8 R9 G9 B9 Ra Ga
-       * rgb2 = Ba Rb Gb Bb Rc Gc Bc Rd Gd Bd Re Ge Be Rf Gf Bf
-       *
-       * rgbg0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 G0 B1 G1 B2 G2 B3 G3
-       * rgbg1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 G4 B5 G5 B6 G6 B7 G7
-       * rgbg2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 G8 B9 G9 Ba Ga Bb Gb
-       * rgbg3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Gc Bd Gd Be Ge Bf Gf
-       */
-      rgbg0 = vec_perm(rgb0, rgb0, (__vector unsigned char)RGBG_INDEX0);
-      rgbg1 = vec_perm(rgb0, rgb1, (__vector unsigned char)RGBG_INDEX1);
-      rgbg2 = vec_perm(rgb1, rgb2, (__vector unsigned char)RGBG_INDEX2);
-      rgbg3 = vec_perm(rgb2, rgb2, (__vector unsigned char)RGBG_INDEX3);
-#else
-      /* rgb0 = R0 G0 B0 X0 R1 G1 B1 X1 R2 G2 B2 X2 R3 G3 B3 X3
-       * rgb1 = R4 G4 B4 X4 R5 G5 B5 X5 R6 G6 B6 X6 R7 G7 B7 X7
-       * rgb2 = R8 G8 B8 X8 R9 G9 B9 X9 Ra Ga Ba Xa Rb Gb Bb Xb
-       * rgb3 = Rc Gc Bc Xc Rd Gd Bd Xd Re Ge Be Xe Rf Gf Bf Xf
-       *
-       * rgbg0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 G0 B1 G1 B2 G2 B3 G3
-       * rgbg1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 G4 B5 G5 B6 G6 B7 G7
-       * rgbg2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 G8 B9 G9 Ba Ga Bb Gb
-       * rgbg3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Gc Bd Gd Be Ge Bf Gf
-       */
-      rgbg0 = vec_perm(rgb0, rgb0, (__vector unsigned char)RGBG_INDEX);
-      rgbg1 = vec_perm(rgb1, rgb1, (__vector unsigned char)RGBG_INDEX);
-      rgbg2 = vec_perm(rgb2, rgb2, (__vector unsigned char)RGBG_INDEX);
-      rgbg3 = vec_perm(rgb3, rgb3, (__vector unsigned char)RGBG_INDEX);
-#endif
-
-      /* rg0 = R0 G0 R1 G1 R2 G2 R3 G3
-       * bg0 = B0 G0 B1 G1 B2 G2 B3 G3
-       * ...
-       *
-       * NOTE: We have to use vec_merge*() here because vec_unpack*() doesn't
-       * support unsigned vectors.
-       */
-      rg0 = (__vector signed short)VEC_UNPACKHU(rgbg0);
-      bg0 = (__vector signed short)VEC_UNPACKLU(rgbg0);
-      rg1 = (__vector signed short)VEC_UNPACKHU(rgbg1);
-      bg1 = (__vector signed short)VEC_UNPACKLU(rgbg1);
-      rg2 = (__vector signed short)VEC_UNPACKHU(rgbg2);
-      bg2 = (__vector signed short)VEC_UNPACKLU(rgbg2);
-      rg3 = (__vector signed short)VEC_UNPACKHU(rgbg3);
-      bg3 = (__vector signed short)VEC_UNPACKLU(rgbg3);
-
-      /* (Original)
-       * Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
-       * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
-       * Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
-       *
-       * (This implementation)
-       * Y  =  0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
-       * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
-       * Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
-       */
-
-      /* Calculate Y values */
-
-      y0 = vec_msums(rg0, pw_f0299_f0337, pd_onehalf);
-      y1 = vec_msums(rg1, pw_f0299_f0337, pd_onehalf);
-      y2 = vec_msums(rg2, pw_f0299_f0337, pd_onehalf);
-      y3 = vec_msums(rg3, pw_f0299_f0337, pd_onehalf);
-      y0 = vec_msums(bg0, pw_f0114_f0250, y0);
-      y1 = vec_msums(bg1, pw_f0114_f0250, y1);
-      y2 = vec_msums(bg2, pw_f0114_f0250, y2);
-      y3 = vec_msums(bg3, pw_f0114_f0250, y3);
-      /* Clever way to avoid 4 shifts + 2 packs.  This packs the high word from
-       * each dword into a new 16-bit vector, which is the equivalent of
-       * descaling the 32-bit results (right-shifting by 16 bits) and then
-       * packing them.
-       */
-      yl = vec_perm((__vector unsigned short)y0, (__vector unsigned short)y1,
-                    shift_pack_index);
-      yh = vec_perm((__vector unsigned short)y2, (__vector unsigned short)y3,
-                    shift_pack_index);
-      y = vec_pack(yl, yh);
-      vec_st(y, 0, outptr0);
-
-      /* Calculate Cb values */
-      cb0 = vec_msums(rg0, pw_mf016_mf033, pd_onehalfm1_cj);
-      cb1 = vec_msums(rg1, pw_mf016_mf033, pd_onehalfm1_cj);
-      cb2 = vec_msums(rg2, pw_mf016_mf033, pd_onehalfm1_cj);
-      cb3 = vec_msums(rg3, pw_mf016_mf033, pd_onehalfm1_cj);
-      cb0 = (__vector int)vec_msum((__vector unsigned short)bg0, pw_f050_f000,
-                                   (__vector unsigned int)cb0);
-      cb1 = (__vector int)vec_msum((__vector unsigned short)bg1, pw_f050_f000,
-                                   (__vector unsigned int)cb1);
-      cb2 = (__vector int)vec_msum((__vector unsigned short)bg2, pw_f050_f000,
-                                   (__vector unsigned int)cb2);
-      cb3 = (__vector int)vec_msum((__vector unsigned short)bg3, pw_f050_f000,
-                                   (__vector unsigned int)cb3);
-      cbl = vec_perm((__vector unsigned short)cb0,
-                     (__vector unsigned short)cb1, shift_pack_index);
-      cbh = vec_perm((__vector unsigned short)cb2,
-                     (__vector unsigned short)cb3, shift_pack_index);
-      cb = vec_pack(cbl, cbh);
-      vec_st(cb, 0, outptr1);
-
-      /* Calculate Cr values */
-      cr0 = vec_msums(bg0, pw_mf008_mf041, pd_onehalfm1_cj);
-      cr1 = vec_msums(bg1, pw_mf008_mf041, pd_onehalfm1_cj);
-      cr2 = vec_msums(bg2, pw_mf008_mf041, pd_onehalfm1_cj);
-      cr3 = vec_msums(bg3, pw_mf008_mf041, pd_onehalfm1_cj);
-      cr0 = (__vector int)vec_msum((__vector unsigned short)rg0, pw_f050_f000,
-                                   (__vector unsigned int)cr0);
-      cr1 = (__vector int)vec_msum((__vector unsigned short)rg1, pw_f050_f000,
-                                   (__vector unsigned int)cr1);
-      cr2 = (__vector int)vec_msum((__vector unsigned short)rg2, pw_f050_f000,
-                                   (__vector unsigned int)cr2);
-      cr3 = (__vector int)vec_msum((__vector unsigned short)rg3, pw_f050_f000,
-                                   (__vector unsigned int)cr3);
-      crl = vec_perm((__vector unsigned short)cr0,
-                     (__vector unsigned short)cr1, shift_pack_index);
-      crh = vec_perm((__vector unsigned short)cr2,
-                     (__vector unsigned short)cr3, shift_pack_index);
-      cr = vec_pack(crl, crh);
-      vec_st(cr, 0, outptr2);
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jccolor-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jccolor-altivec.c
deleted file mode 100644
index d670dbc..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jccolor-altivec.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* RGB --> YCC CONVERSION */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_081  5329                 /* FIX(0.08131) */
-#define F_0_114  7471                 /* FIX(0.11400) */
-#define F_0_168  11059                /* FIX(0.16874) */
-#define F_0_250  16384                /* FIX(0.25000) */
-#define F_0_299  19595                /* FIX(0.29900) */
-#define F_0_331  21709                /* FIX(0.33126) */
-#define F_0_418  27439                /* FIX(0.41869) */
-#define F_0_500  32768                /* FIX(0.50000) */
-#define F_0_587  38470                /* FIX(0.58700) */
-#define F_0_337  (F_0_587 - F_0_250)  /* FIX(0.58700) - FIX(0.25000) */
-
-#define SCALEBITS  16
-#define ONE_HALF  (1 << (SCALEBITS - 1))
-
-
-#define RGBG_INDEX0 \
-  {  0,  1,  3,  4,  6,  7,  9, 10,  2,  1,  5,  4,  8,  7, 11, 10 }
-#define RGBG_INDEX1 \
-  { 12, 13, 15, 16, 18, 19, 21, 22, 14, 13, 17, 16, 20, 19, 23, 22 }
-#define RGBG_INDEX2 \
-  {  8,  9, 11, 12, 14, 15, 17, 18, 10,  9, 13, 12, 16, 15, 19, 18 }
-#define RGBG_INDEX3 \
-  {  4,  5,  7,  8, 10, 11, 13, 14,  6,  5,  9,  8, 12, 11, 15, 14 }
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extrgb_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX0
-#undef RGBG_INDEX1
-#undef RGBG_INDEX2
-#undef RGBG_INDEX3
-#undef jsimd_rgb_ycc_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define RGBG_INDEX \
-  {  0,  1,  4,  5,  8,  9, 12, 13,  2,  1,  6,  5, 10,  9, 14, 13 }
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extrgbx_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_ycc_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define RGBG_INDEX0 \
-  {  2,  1,  5,  4,  8,  7, 11, 10,  0,  1,  3,  4,  6,  7,  9, 10 }
-#define RGBG_INDEX1 \
-  { 14, 13, 17, 16, 20, 19, 23, 22, 12, 13, 15, 16, 18, 19, 21, 22 }
-#define RGBG_INDEX2 \
-  { 10,  9, 13, 12, 16, 15, 19, 18,  8,  9, 11, 12, 14, 15, 17, 18 }
-#define RGBG_INDEX3 \
-  {  6,  5,  9,  8, 12, 11, 15, 14,  4,  5,  7,  8, 10, 11, 13, 14 }
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extbgr_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX0
-#undef RGBG_INDEX1
-#undef RGBG_INDEX2
-#undef RGBG_INDEX3
-#undef jsimd_rgb_ycc_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define RGBG_INDEX \
-  {  2,  1,  6,  5, 10,  9, 14, 13,  0,  1,  4,  5,  8,  9, 12, 13 }
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extbgrx_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_ycc_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define RGBG_INDEX \
-  {  3,  2,  7,  6, 11, 10, 15, 14,  1,  2,  5,  6,  9, 10, 13, 14 }
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extxbgr_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_ycc_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define RGBG_INDEX \
-  {  1,  2,  5,  6,  9, 10, 13, 14,  3,  2,  7,  6, 11, 10, 15, 14 }
-#define jsimd_rgb_ycc_convert_altivec  jsimd_extxrgb_ycc_convert_altivec
-#include "jccolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_ycc_convert_altivec
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jcgray-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jcgray-altivec.c
deleted file mode 100644
index a11a7e7..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jcgray-altivec.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* RGB --> GRAYSCALE CONVERSION */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_114  7471                 /* FIX(0.11400) */
-#define F_0_250  16384                /* FIX(0.25000) */
-#define F_0_299  19595                /* FIX(0.29900) */
-#define F_0_587  38470                /* FIX(0.58700) */
-#define F_0_337  (F_0_587 - F_0_250)  /* FIX(0.58700) - FIX(0.25000) */
-
-#define SCALEBITS  16
-#define ONE_HALF  (1 << (SCALEBITS - 1))
-
-
-#define RGBG_INDEX0 \
-  {  0,  1,  3,  4,  6,  7,  9, 10,  2,  1,  5,  4,  8,  7, 11, 10 }
-#define RGBG_INDEX1 \
-  { 12, 13, 15, 16, 18, 19, 21, 22, 14, 13, 17, 16, 20, 19, 23, 22 }
-#define RGBG_INDEX2 \
-  {  8,  9, 11, 12, 14, 15, 17, 18, 10,  9, 13, 12, 16, 15, 19, 18 }
-#define RGBG_INDEX3 \
-  {  4,  5,  7,  8, 10, 11, 13, 14,  6,  5,  9,  8, 12, 11, 15, 14 }
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_rgb_gray_convert_altivec  jsimd_extrgb_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX0
-#undef RGBG_INDEX1
-#undef RGBG_INDEX2
-#undef RGBG_INDEX3
-#undef jsimd_rgb_gray_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define RGBG_INDEX \
-  {  0,  1,  4,  5,  8,  9, 12, 13,  2,  1,  6,  5, 10,  9, 14, 13 }
-#define jsimd_rgb_gray_convert_altivec  jsimd_extrgbx_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_gray_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define RGBG_INDEX0 \
-  {  2,  1,  5,  4,  8,  7, 11, 10,  0,  1,  3,  4,  6,  7,  9, 10 }
-#define RGBG_INDEX1 \
-  { 14, 13, 17, 16, 20, 19, 23, 22, 12, 13, 15, 16, 18, 19, 21, 22 }
-#define RGBG_INDEX2 \
-  { 10,  9, 13, 12, 16, 15, 19, 18,  8,  9, 11, 12, 14, 15, 17, 18 }
-#define RGBG_INDEX3 \
-  {  6,  5,  9,  8, 12, 11, 15, 14,  4,  5,  7,  8, 10, 11, 13, 14 }
-#define jsimd_rgb_gray_convert_altivec  jsimd_extbgr_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX0
-#undef RGBG_INDEX1
-#undef RGBG_INDEX2
-#undef RGBG_INDEX3
-#undef jsimd_rgb_gray_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define RGBG_INDEX \
-  {  2,  1,  6,  5, 10,  9, 14, 13,  0,  1,  4,  5,  8,  9, 12, 13 }
-#define jsimd_rgb_gray_convert_altivec  jsimd_extbgrx_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_gray_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define RGBG_INDEX \
-  {  3,  2,  7,  6, 11, 10, 15, 14,  1,  2,  5,  6,  9, 10, 13, 14 }
-#define jsimd_rgb_gray_convert_altivec  jsimd_extxbgr_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_gray_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define RGBG_INDEX \
-  {  1,  2,  5,  6,  9, 10, 13, 14,  3,  2,  7,  6, 11, 10, 15, 14 }
-#define jsimd_rgb_gray_convert_altivec  jsimd_extxrgb_gray_convert_altivec
-#include "jcgryext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGBG_INDEX
-#undef jsimd_rgb_gray_convert_altivec
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jcgryext-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jcgryext-altivec.c
deleted file mode 100644
index b280cbb..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jcgryext-altivec.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- * Copyright (C) 2014, Jay Foad.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jcgray-altivec.c */
-
-
-void jsimd_rgb_gray_convert_altivec(JDIMENSION img_width, JSAMPARRAY input_buf,
-                                    JSAMPIMAGE output_buf,
-                                    JDIMENSION output_row, int num_rows)
-{
-  JSAMPROW inptr, outptr;
-  int pitch = img_width * RGB_PIXELSIZE, num_cols;
-#if __BIG_ENDIAN__
-  int offset;
-  unsigned char __attribute__((aligned(16))) tmpbuf[RGB_PIXELSIZE * 16];
-#endif
-
-  __vector unsigned char rgb0, rgb1 = { 0 }, rgb2 = { 0 },
-    rgbg0, rgbg1, rgbg2, rgbg3, y;
-#if __BIG_ENDIAN__ || RGB_PIXELSIZE == 4
-  __vector unsigned char rgb3 = { 0 };
-#endif
-#if __BIG_ENDIAN__ && RGB_PIXELSIZE == 4
-  __vector unsigned char rgb4 = { 0 };
-#endif
-  __vector short rg0, rg1, rg2, rg3, bg0, bg1, bg2, bg3;
-  __vector unsigned short yl, yh;
-  __vector int y0, y1, y2, y3;
-
-  /* Constants */
-  __vector short pw_f0299_f0337 = { __4X2(F_0_299, F_0_337) },
-    pw_f0114_f0250 = { __4X2(F_0_114, F_0_250) };
-  __vector int pd_onehalf = { __4X(ONE_HALF) };
-  __vector unsigned char pb_zero = { __16X(0) },
-#if __BIG_ENDIAN__
-    shift_pack_index =
-      { 0, 1, 4, 5,  8,  9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 };
-#else
-    shift_pack_index =
-      { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 };
-#endif
-
-  while (--num_rows >= 0) {
-    inptr = *input_buf++;
-    outptr = output_buf[0][output_row];
-    output_row++;
-
-    for (num_cols = pitch; num_cols > 0;
-         num_cols -= RGB_PIXELSIZE * 16, inptr += RGB_PIXELSIZE * 16,
-         outptr += 16) {
-
-#if __BIG_ENDIAN__
-      /* Load 16 pixels == 48 or 64 bytes */
-      offset = (size_t)inptr & 15;
-      if (offset) {
-        __vector unsigned char unaligned_shift_index;
-        int bytes = num_cols + offset;
-
-        if (bytes < (RGB_PIXELSIZE + 1) * 16 && (bytes & 15)) {
-          /* Slow path to prevent buffer overread.  Since there is no way to
-           * read a partial AltiVec register, overread would occur on the last
-           * chunk of the last image row if the right edge is not on a 16-byte
-           * boundary.  It could also occur on other rows if the bytes per row
-           * is low enough.  Since we can't determine whether we're on the last
-           * image row, we have to assume every row is the last.
-           */
-          memcpy(tmpbuf, inptr, min(num_cols, RGB_PIXELSIZE * 16));
-          rgb0 = vec_ld(0, tmpbuf);
-          rgb1 = vec_ld(16, tmpbuf);
-          rgb2 = vec_ld(32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          rgb3 = vec_ld(48, tmpbuf);
-#endif
-        } else {
-          /* Fast path */
-          rgb0 = vec_ld(0, inptr);
-          if (bytes > 16)
-            rgb1 = vec_ld(16, inptr);
-          if (bytes > 32)
-            rgb2 = vec_ld(32, inptr);
-          if (bytes > 48)
-            rgb3 = vec_ld(48, inptr);
-#if RGB_PIXELSIZE == 4
-          if (bytes > 64)
-            rgb4 = vec_ld(64, inptr);
-#endif
-          unaligned_shift_index = vec_lvsl(0, inptr);
-          rgb0 = vec_perm(rgb0, rgb1, unaligned_shift_index);
-          rgb1 = vec_perm(rgb1, rgb2, unaligned_shift_index);
-          rgb2 = vec_perm(rgb2, rgb3, unaligned_shift_index);
-#if RGB_PIXELSIZE == 4
-          rgb3 = vec_perm(rgb3, rgb4, unaligned_shift_index);
-#endif
-        }
-      } else {
-        if (num_cols < RGB_PIXELSIZE * 16 && (num_cols & 15)) {
-          /* Slow path */
-          memcpy(tmpbuf, inptr, min(num_cols, RGB_PIXELSIZE * 16));
-          rgb0 = vec_ld(0, tmpbuf);
-          rgb1 = vec_ld(16, tmpbuf);
-          rgb2 = vec_ld(32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          rgb3 = vec_ld(48, tmpbuf);
-#endif
-        } else {
-          /* Fast path */
-          rgb0 = vec_ld(0, inptr);
-          if (num_cols > 16)
-            rgb1 = vec_ld(16, inptr);
-          if (num_cols > 32)
-            rgb2 = vec_ld(32, inptr);
-#if RGB_PIXELSIZE == 4
-          if (num_cols > 48)
-            rgb3 = vec_ld(48, inptr);
-#endif
-        }
-      }
-#else
-      /* Little endian */
-      rgb0 = vec_vsx_ld(0, inptr);
-      if (num_cols > 16)
-        rgb1 = vec_vsx_ld(16, inptr);
-      if (num_cols > 32)
-        rgb2 = vec_vsx_ld(32, inptr);
-#if RGB_PIXELSIZE == 4
-      if (num_cols > 48)
-        rgb3 = vec_vsx_ld(48, inptr);
-#endif
-#endif
-
-#if RGB_PIXELSIZE == 3
-      /* rgb0 = R0 G0 B0 R1 G1 B1 R2 G2 B2 R3 G3 B3 R4 G4 B4 R5
-       * rgb1 = G5 B5 R6 G6 B6 R7 G7 B7 R8 G8 B8 R9 G9 B9 Ra Ga
-       * rgb2 = Ba Rb Gb Bb Rc Gc Bc Rd Gd Bd Re Ge Be Rf Gf Bf
-       *
-       * rgbg0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 G0 B1 G1 B2 G2 B3 G3
-       * rgbg1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 G4 B5 G5 B6 G6 B7 G7
-       * rgbg2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 G8 B9 G9 Ba Ga Bb Gb
-       * rgbg3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Gc Bd Gd Be Ge Bf Gf
-       */
-      rgbg0 = vec_perm(rgb0, rgb0, (__vector unsigned char)RGBG_INDEX0);
-      rgbg1 = vec_perm(rgb0, rgb1, (__vector unsigned char)RGBG_INDEX1);
-      rgbg2 = vec_perm(rgb1, rgb2, (__vector unsigned char)RGBG_INDEX2);
-      rgbg3 = vec_perm(rgb2, rgb2, (__vector unsigned char)RGBG_INDEX3);
-#else
-      /* rgb0 = R0 G0 B0 X0 R1 G1 B1 X1 R2 G2 B2 X2 R3 G3 B3 X3
-       * rgb1 = R4 G4 B4 X4 R5 G5 B5 X5 R6 G6 B6 X6 R7 G7 B7 X7
-       * rgb2 = R8 G8 B8 X8 R9 G9 B9 X9 Ra Ga Ba Xa Rb Gb Bb Xb
-       * rgb3 = Rc Gc Bc Xc Rd Gd Bd Xd Re Ge Be Xe Rf Gf Bf Xf
-       *
-       * rgbg0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 G0 B1 G1 B2 G2 B3 G3
-       * rgbg1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 G4 B5 G5 B6 G6 B7 G7
-       * rgbg2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 G8 B9 G9 Ba Ga Bb Gb
-       * rgbg3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Gc Bd Gd Be Ge Bf Gf
-       */
-      rgbg0 = vec_perm(rgb0, rgb0, (__vector unsigned char)RGBG_INDEX);
-      rgbg1 = vec_perm(rgb1, rgb1, (__vector unsigned char)RGBG_INDEX);
-      rgbg2 = vec_perm(rgb2, rgb2, (__vector unsigned char)RGBG_INDEX);
-      rgbg3 = vec_perm(rgb3, rgb3, (__vector unsigned char)RGBG_INDEX);
-#endif
-
-      /* rg0 = R0 G0 R1 G1 R2 G2 R3 G3
-       * bg0 = B0 G0 B1 G1 B2 G2 B3 G3
-       * ...
-       *
-       * NOTE: We have to use vec_merge*() here because vec_unpack*() doesn't
-       * support unsigned vectors.
-       */
-      rg0 = (__vector signed short)VEC_UNPACKHU(rgbg0);
-      bg0 = (__vector signed short)VEC_UNPACKLU(rgbg0);
-      rg1 = (__vector signed short)VEC_UNPACKHU(rgbg1);
-      bg1 = (__vector signed short)VEC_UNPACKLU(rgbg1);
-      rg2 = (__vector signed short)VEC_UNPACKHU(rgbg2);
-      bg2 = (__vector signed short)VEC_UNPACKLU(rgbg2);
-      rg3 = (__vector signed short)VEC_UNPACKHU(rgbg3);
-      bg3 = (__vector signed short)VEC_UNPACKLU(rgbg3);
-
-      /* (Original)
-       * Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
-       *
-       * (This implementation)
-       * Y  =  0.29900 * R + 0.33700 * G + 0.11400 * B + 0.25000 * G
-       */
-
-      /* Calculate Y values */
-
-      y0 = vec_msums(rg0, pw_f0299_f0337, pd_onehalf);
-      y1 = vec_msums(rg1, pw_f0299_f0337, pd_onehalf);
-      y2 = vec_msums(rg2, pw_f0299_f0337, pd_onehalf);
-      y3 = vec_msums(rg3, pw_f0299_f0337, pd_onehalf);
-      y0 = vec_msums(bg0, pw_f0114_f0250, y0);
-      y1 = vec_msums(bg1, pw_f0114_f0250, y1);
-      y2 = vec_msums(bg2, pw_f0114_f0250, y2);
-      y3 = vec_msums(bg3, pw_f0114_f0250, y3);
-      /* Clever way to avoid 4 shifts + 2 packs.  This packs the high word from
-       * each dword into a new 16-bit vector, which is the equivalent of
-       * descaling the 32-bit results (right-shifting by 16 bits) and then
-       * packing them.
-       */
-      yl = vec_perm((__vector unsigned short)y0, (__vector unsigned short)y1,
-                    shift_pack_index);
-      yh = vec_perm((__vector unsigned short)y2, (__vector unsigned short)y3,
-                    shift_pack_index);
-      y = vec_pack(yl, yh);
-      vec_st(y, 0, outptr);
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jcsample-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jcsample-altivec.c
deleted file mode 100644
index 6e25b8d..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jcsample-altivec.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* CHROMA DOWNSAMPLING */
-
-#include "jsimd_altivec.h"
-#include "jcsample.h"
-
-
-void jsimd_h2v1_downsample_altivec(JDIMENSION image_width,
-                                   int max_v_samp_factor,
-                                   JDIMENSION v_samp_factor,
-                                   JDIMENSION width_in_blocks,
-                                   JSAMPARRAY input_data,
-                                   JSAMPARRAY output_data)
-{
-  int outrow, outcol;
-  JDIMENSION output_cols = width_in_blocks * DCTSIZE;
-  JSAMPROW inptr, outptr;
-
-  __vector unsigned char this0, next0, out;
-  __vector unsigned short this0e, this0o, next0e, next0o, outl, outh;
-
-  /* Constants */
-  __vector unsigned short pw_bias = { __4X2(0, 1) },
-    pw_one = { __8X(1) };
-  __vector unsigned char even_odd_index =
-    {  0,  2,  4,  6,  8, 10, 12, 14,  1,  3,  5,  7,  9, 11, 13, 15 },
-    pb_zero = { __16X(0) };
-
-  expand_right_edge(input_data, max_v_samp_factor, image_width,
-                    output_cols * 2);
-
-  for (outrow = 0; outrow < v_samp_factor; outrow++) {
-    outptr = output_data[outrow];
-    inptr = input_data[outrow];
-
-    for (outcol = output_cols; outcol > 0;
-         outcol -= 16, inptr += 32, outptr += 16) {
-
-      this0 = vec_ld(0, inptr);
-      this0 = vec_perm(this0, this0, even_odd_index);
-      this0e = (__vector unsigned short)VEC_UNPACKHU(this0);
-      this0o = (__vector unsigned short)VEC_UNPACKLU(this0);
-      outl = vec_add(this0e, this0o);
-      outl = vec_add(outl, pw_bias);
-      outl = vec_sr(outl, pw_one);
-
-      if (outcol > 8) {
-        next0 = vec_ld(16, inptr);
-        next0 = vec_perm(next0, next0, even_odd_index);
-        next0e = (__vector unsigned short)VEC_UNPACKHU(next0);
-        next0o = (__vector unsigned short)VEC_UNPACKLU(next0);
-        outh = vec_add(next0e, next0o);
-        outh = vec_add(outh, pw_bias);
-        outh = vec_sr(outh, pw_one);
-      } else
-        outh = vec_splat_u16(0);
-
-      out = vec_pack(outl, outh);
-      vec_st(out, 0, outptr);
-    }
-  }
-}
-
-
-void
-jsimd_h2v2_downsample_altivec(JDIMENSION image_width, int max_v_samp_factor,
-                              JDIMENSION v_samp_factor,
-                              JDIMENSION width_in_blocks,
-                              JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  int inrow, outrow, outcol;
-  JDIMENSION output_cols = width_in_blocks * DCTSIZE;
-  JSAMPROW inptr0, inptr1, outptr;
-
-  __vector unsigned char this0, next0, this1, next1, out;
-  __vector unsigned short this0e, this0o, next0e, next0o, this1e, this1o,
-    next1e, next1o, out0l, out0h, out1l, out1h, outl, outh;
-
-  /* Constants */
-  __vector unsigned short pw_bias = { __4X2(1, 2) },
-    pw_two = { __8X(2) };
-  __vector unsigned char even_odd_index =
-    {  0,  2,  4,  6,  8, 10, 12, 14,  1,  3,  5,  7,  9, 11, 13, 15 },
-    pb_zero = { __16X(0) };
-
-  expand_right_edge(input_data, max_v_samp_factor, image_width,
-                    output_cols * 2);
-
-  for (inrow = 0, outrow = 0; outrow < v_samp_factor;
-       inrow += 2, outrow++) {
-
-    inptr0 = input_data[inrow];
-    inptr1 = input_data[inrow + 1];
-    outptr = output_data[outrow];
-
-    for (outcol = output_cols; outcol > 0;
-         outcol -= 16, inptr0 += 32, inptr1 += 32, outptr += 16) {
-
-      this0 = vec_ld(0, inptr0);
-      this0 = vec_perm(this0, this0, even_odd_index);
-      this0e = (__vector unsigned short)VEC_UNPACKHU(this0);
-      this0o = (__vector unsigned short)VEC_UNPACKLU(this0);
-      out0l = vec_add(this0e, this0o);
-
-      this1 = vec_ld(0, inptr1);
-      this1 = vec_perm(this1, this1, even_odd_index);
-      this1e = (__vector unsigned short)VEC_UNPACKHU(this1);
-      this1o = (__vector unsigned short)VEC_UNPACKLU(this1);
-      out1l = vec_add(this1e, this1o);
-
-      outl = vec_add(out0l, out1l);
-      outl = vec_add(outl, pw_bias);
-      outl = vec_sr(outl, pw_two);
-
-      if (outcol > 8) {
-        next0 = vec_ld(16, inptr0);
-        next0 = vec_perm(next0, next0, even_odd_index);
-        next0e = (__vector unsigned short)VEC_UNPACKHU(next0);
-        next0o = (__vector unsigned short)VEC_UNPACKLU(next0);
-        out0h = vec_add(next0e, next0o);
-
-        next1 = vec_ld(16, inptr1);
-        next1 = vec_perm(next1, next1, even_odd_index);
-        next1e = (__vector unsigned short)VEC_UNPACKHU(next1);
-        next1o = (__vector unsigned short)VEC_UNPACKLU(next1);
-        out1h = vec_add(next1e, next1o);
-
-        outh = vec_add(out0h, out1h);
-        outh = vec_add(outh, pw_bias);
-        outh = vec_sr(outh, pw_two);
-      } else
-        outh = vec_splat_u16(0);
-
-      out = vec_pack(outl, outh);
-      vec_st(out, 0, outptr);
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jcsample.h b/src/third_party/libjpeg-turbo/simd/powerpc/jcsample.h
deleted file mode 100644
index 2ac4816..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jcsample.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * jcsample.h
- *
- * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1991-1996, Thomas G. Lane.
- * For conditions of distribution and use, see the accompanying README.ijg
- * file.
- */
-
-LOCAL(void)
-expand_right_edge(JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols,
-                  JDIMENSION output_cols)
-{
-  register JSAMPROW ptr;
-  register JSAMPLE pixval;
-  register int count;
-  int row;
-  int numcols = (int)(output_cols - input_cols);
-
-  if (numcols > 0) {
-    for (row = 0; row < num_rows; row++) {
-      ptr = image_data[row] + input_cols;
-      pixval = ptr[-1];         /* don't need GETJSAMPLE() here */
-      for (count = numcols; count > 0; count--)
-        *ptr++ = pixval;
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jdcolext-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jdcolext-altivec.c
deleted file mode 100644
index 68d52bd..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jdcolext-altivec.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jdcolor-altivec.c */
-
-
-void jsimd_ycc_rgb_convert_altivec(JDIMENSION out_width, JSAMPIMAGE input_buf,
-                                   JDIMENSION input_row, JSAMPARRAY output_buf,
-                                   int num_rows)
-{
-  JSAMPROW outptr, inptr0, inptr1, inptr2;
-  int pitch = out_width * RGB_PIXELSIZE, num_cols;
-#if __BIG_ENDIAN__
-  int offset;
-#endif
-  unsigned char __attribute__((aligned(16))) tmpbuf[RGB_PIXELSIZE * 16];
-
-  __vector unsigned char rgb0, rgb1, rgb2, rgbx0, rgbx1, rgbx2, rgbx3,
-    y, cb, cr;
-#if __BIG_ENDIAN__
-  __vector unsigned char edgel, edgeh, edges, out0, out1, out2, out3;
-#if RGB_PIXELSIZE == 4
-  __vector unsigned char out4;
-#endif
-#endif
-#if RGB_PIXELSIZE == 4
-  __vector unsigned char rgb3;
-#endif
-  __vector short rg0, rg1, rg2, rg3, bx0, bx1, bx2, bx3, yl, yh, cbl, cbh,
-    crl, crh, rl, rh, gl, gh, bl, bh, g0w, g1w, g2w, g3w;
-  __vector int g0, g1, g2, g3;
-
-  /* Constants
-   * NOTE: The >> 1 is to compensate for the fact that vec_madds() returns 17
-   * high-order bits, not 16.
-   */
-  __vector short pw_f0402 = { __8X(F_0_402 >> 1) },
-    pw_mf0228 = { __8X(-F_0_228 >> 1) },
-    pw_mf0344_f0285 = { __4X2(-F_0_344, F_0_285) },
-    pw_one = { __8X(1) }, pw_255 = { __8X(255) },
-    pw_cj = { __8X(CENTERJSAMPLE) };
-  __vector int pd_onehalf = { __4X(ONE_HALF) };
-  __vector unsigned char pb_zero = { __16X(0) },
-#if __BIG_ENDIAN__
-    shift_pack_index =
-      {  0,  1,  4,  5,  8,  9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 };
-#else
-    shift_pack_index =
-      {  2,  3,  6,  7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 };
-#endif
-
-  while (--num_rows >= 0) {
-    inptr0 = input_buf[0][input_row];
-    inptr1 = input_buf[1][input_row];
-    inptr2 = input_buf[2][input_row];
-    input_row++;
-    outptr = *output_buf++;
-
-    for (num_cols = pitch; num_cols > 0;
-         num_cols -= RGB_PIXELSIZE * 16, outptr += RGB_PIXELSIZE * 16,
-         inptr0 += 16, inptr1 += 16, inptr2 += 16) {
-
-      y = vec_ld(0, inptr0);
-      /* NOTE: We have to use vec_merge*() here because vec_unpack*() doesn't
-       * support unsigned vectors.
-       */
-      yl = (__vector signed short)VEC_UNPACKHU(y);
-      yh = (__vector signed short)VEC_UNPACKLU(y);
-
-      cb = vec_ld(0, inptr1);
-      cbl = (__vector signed short)VEC_UNPACKHU(cb);
-      cbh = (__vector signed short)VEC_UNPACKLU(cb);
-      cbl = vec_sub(cbl, pw_cj);
-      cbh = vec_sub(cbh, pw_cj);
-
-      cr = vec_ld(0, inptr2);
-      crl = (__vector signed short)VEC_UNPACKHU(cr);
-      crh = (__vector signed short)VEC_UNPACKLU(cr);
-      crl = vec_sub(crl, pw_cj);
-      crh = vec_sub(crh, pw_cj);
-
-      /* (Original)
-       * R = Y                + 1.40200 * Cr
-       * G = Y - 0.34414 * Cb - 0.71414 * Cr
-       * B = Y + 1.77200 * Cb
-       *
-       * (This implementation)
-       * R = Y                + 0.40200 * Cr + Cr
-       * G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
-       * B = Y - 0.22800 * Cb + Cb + Cb
-       */
-      bl = vec_add(cbl, cbl);
-      bh = vec_add(cbh, cbh);
-      bl = vec_madds(bl, pw_mf0228, pw_one);
-      bh = vec_madds(bh, pw_mf0228, pw_one);
-      bl = vec_sra(bl, (__vector unsigned short)pw_one);
-      bh = vec_sra(bh, (__vector unsigned short)pw_one);
-      bl = vec_add(bl, cbl);
-      bh = vec_add(bh, cbh);
-      bl = vec_add(bl, cbl);
-      bh = vec_add(bh, cbh);
-      bl = vec_add(bl, yl);
-      bh = vec_add(bh, yh);
-
-      rl = vec_add(crl, crl);
-      rh = vec_add(crh, crh);
-      rl = vec_madds(rl, pw_f0402, pw_one);
-      rh = vec_madds(rh, pw_f0402, pw_one);
-      rl = vec_sra(rl, (__vector unsigned short)pw_one);
-      rh = vec_sra(rh, (__vector unsigned short)pw_one);
-      rl = vec_add(rl, crl);
-      rh = vec_add(rh, crh);
-      rl = vec_add(rl, yl);
-      rh = vec_add(rh, yh);
-
-      g0w = vec_mergeh(cbl, crl);
-      g1w = vec_mergel(cbl, crl);
-      g0 = vec_msums(g0w, pw_mf0344_f0285, pd_onehalf);
-      g1 = vec_msums(g1w, pw_mf0344_f0285, pd_onehalf);
-      g2w = vec_mergeh(cbh, crh);
-      g3w = vec_mergel(cbh, crh);
-      g2 = vec_msums(g2w, pw_mf0344_f0285, pd_onehalf);
-      g3 = vec_msums(g3w, pw_mf0344_f0285, pd_onehalf);
-      /* Clever way to avoid 4 shifts + 2 packs.  This packs the high word from
-       * each dword into a new 16-bit vector, which is the equivalent of
-       * descaling the 32-bit results (right-shifting by 16 bits) and then
-       * packing them.
-       */
-      gl = vec_perm((__vector short)g0, (__vector short)g1, shift_pack_index);
-      gh = vec_perm((__vector short)g2, (__vector short)g3, shift_pack_index);
-      gl = vec_sub(gl, crl);
-      gh = vec_sub(gh, crh);
-      gl = vec_add(gl, yl);
-      gh = vec_add(gh, yh);
-
-      rg0 = vec_mergeh(rl, gl);
-      bx0 = vec_mergeh(bl, pw_255);
-      rg1 = vec_mergel(rl, gl);
-      bx1 = vec_mergel(bl, pw_255);
-      rg2 = vec_mergeh(rh, gh);
-      bx2 = vec_mergeh(bh, pw_255);
-      rg3 = vec_mergel(rh, gh);
-      bx3 = vec_mergel(bh, pw_255);
-
-      rgbx0 = vec_packsu(rg0, bx0);
-      rgbx1 = vec_packsu(rg1, bx1);
-      rgbx2 = vec_packsu(rg2, bx2);
-      rgbx3 = vec_packsu(rg3, bx3);
-
-#if RGB_PIXELSIZE == 3
-      /* rgbx0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 X0 B1 X1 B2 X2 B3 X3
-       * rgbx1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 X4 B5 X5 B6 X6 B7 X7
-       * rgbx2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 X8 B9 X9 Ba Xa Bb Xb
-       * rgbx3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Xc Bd Xd Be Xe Bf Xf
-       *
-       * rgb0 = R0 G0 B0 R1 G1 B1 R2 G2 B2 R3 G3 B3 R4 G4 B4 R5
-       * rgb1 = G5 B5 R6 G6 B6 R7 G7 B7 R8 G8 B8 R9 G9 B9 Ra Ga
-       * rgb2 = Ba Rb Gb Bb Rc Gc Bc Rd Gd Bd Re Ge Be Rf Gf Bf
-       */
-      rgb0 = vec_perm(rgbx0, rgbx1, (__vector unsigned char)RGB_INDEX0);
-      rgb1 = vec_perm(rgbx1, rgbx2, (__vector unsigned char)RGB_INDEX1);
-      rgb2 = vec_perm(rgbx2, rgbx3, (__vector unsigned char)RGB_INDEX2);
-#else
-      /* rgbx0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 X0 B1 X1 B2 X2 B3 X3
-       * rgbx1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 X4 B5 X5 B6 X6 B7 X7
-       * rgbx2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 X8 B9 X9 Ba Xa Bb Xb
-       * rgbx3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Xc Bd Xd Be Xe Bf Xf
-       *
-       * rgb0 = R0 G0 B0 X0 R1 G1 B1 X1 R2 G2 B2 X2 R3 G3 B3 X3
-       * rgb1 = R4 G4 B4 X4 R5 G5 B5 X5 R6 G6 B6 X6 R7 G7 B7 X7
-       * rgb2 = R8 G8 B8 X8 R9 G9 B9 X9 Ra Ga Ba Xa Rb Gb Bb Xb
-       * rgb3 = Rc Gc Bc Xc Rd Gd Bd Xd Re Ge Be Xe Rf Gf Bf Xf
-       */
-      rgb0 = vec_perm(rgbx0, rgbx0, (__vector unsigned char)RGB_INDEX);
-      rgb1 = vec_perm(rgbx1, rgbx1, (__vector unsigned char)RGB_INDEX);
-      rgb2 = vec_perm(rgbx2, rgbx2, (__vector unsigned char)RGB_INDEX);
-      rgb3 = vec_perm(rgbx3, rgbx3, (__vector unsigned char)RGB_INDEX);
-#endif
-
-#if __BIG_ENDIAN__
-      offset = (size_t)outptr & 15;
-      if (offset) {
-        __vector unsigned char unaligned_shift_index;
-        int bytes = num_cols + offset;
-
-        if (bytes < (RGB_PIXELSIZE + 1) * 16 && (bytes & 15)) {
-          /* Slow path to prevent buffer overwrite.  Since there is no way to
-           * write a partial AltiVec register, overwrite would occur on the
-           * last chunk of the last image row if the right edge is not on a
-           * 16-byte boundary.  It could also occur on other rows if the bytes
-           * per row is low enough.  Since we can't determine whether we're on
-           * the last image row, we have to assume every row is the last.
-           */
-          vec_st(rgb0, 0, tmpbuf);
-          vec_st(rgb1, 16, tmpbuf);
-          vec_st(rgb2, 32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          vec_st(rgb3, 48, tmpbuf);
-#endif
-          memcpy(outptr, tmpbuf, min(num_cols, RGB_PIXELSIZE * 16));
-        } else {
-          /* Fast path */
-          unaligned_shift_index = vec_lvsl(0, outptr);
-          edgel = vec_ld(0, outptr);
-          edgeh = vec_ld(min(num_cols - 1, RGB_PIXELSIZE * 16), outptr);
-          edges = vec_perm(edgeh, edgel, unaligned_shift_index);
-          unaligned_shift_index = vec_lvsr(0, outptr);
-          out0 = vec_perm(edges, rgb0, unaligned_shift_index);
-          out1 = vec_perm(rgb0, rgb1, unaligned_shift_index);
-          out2 = vec_perm(rgb1, rgb2, unaligned_shift_index);
-#if RGB_PIXELSIZE == 4
-          out3 = vec_perm(rgb2, rgb3, unaligned_shift_index);
-          out4 = vec_perm(rgb3, edges, unaligned_shift_index);
-#else
-          out3 = vec_perm(rgb2, edges, unaligned_shift_index);
-#endif
-          vec_st(out0, 0, outptr);
-          if (bytes > 16)
-            vec_st(out1, 16, outptr);
-          if (bytes > 32)
-            vec_st(out2, 32, outptr);
-          if (bytes > 48)
-            vec_st(out3, 48, outptr);
-#if RGB_PIXELSIZE == 4
-          if (bytes > 64)
-            vec_st(out4, 64, outptr);
-#endif
-        }
-      } else {
-#endif /* __BIG_ENDIAN__ */
-        if (num_cols < RGB_PIXELSIZE * 16 && (num_cols & 15)) {
-          /* Slow path */
-          VEC_ST(rgb0, 0, tmpbuf);
-          VEC_ST(rgb1, 16, tmpbuf);
-          VEC_ST(rgb2, 32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          VEC_ST(rgb3, 48, tmpbuf);
-#endif
-          memcpy(outptr, tmpbuf, min(num_cols, RGB_PIXELSIZE * 16));
-        } else {
-          /* Fast path */
-          VEC_ST(rgb0, 0, outptr);
-          if (num_cols > 16)
-            VEC_ST(rgb1, 16, outptr);
-          if (num_cols > 32)
-            VEC_ST(rgb2, 32, outptr);
-#if RGB_PIXELSIZE == 4
-          if (num_cols > 48)
-            VEC_ST(rgb3, 48, outptr);
-#endif
-        }
-#if __BIG_ENDIAN__
-      }
-#endif
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jdcolor-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jdcolor-altivec.c
deleted file mode 100644
index eb35b67..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jdcolor-altivec.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* YCC --> RGB CONVERSION */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_344  22554              /* FIX(0.34414) */
-#define F_0_714  46802              /* FIX(0.71414) */
-#define F_1_402  91881              /* FIX(1.40200) */
-#define F_1_772  116130             /* FIX(1.77200) */
-#define F_0_402  (F_1_402 - 65536)  /* FIX(1.40200) - FIX(1) */
-#define F_0_285  (65536 - F_0_714)  /* FIX(1) - FIX(0.71414) */
-#define F_0_228  (131072 - F_1_772) /* FIX(2) - FIX(1.77200) */
-
-#define SCALEBITS  16
-#define ONE_HALF  (1 << (SCALEBITS - 1))
-
-#define RGB_INDEX0 \
-  {  0,  1,  8,  2,  3, 10,  4,  5, 12,  6,  7, 14, 16, 17, 24, 18 }
-#define RGB_INDEX1 \
-  {  3, 10,  4,  5, 12,  6,  7, 14, 16, 17, 24, 18, 19, 26, 20, 21 }
-#define RGB_INDEX2 \
-  { 12,  6,  7, 14, 16, 17, 24, 18, 19, 26, 20, 21, 28, 22, 23, 30 }
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extrgb_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX0
-#undef RGB_INDEX1
-#undef RGB_INDEX2
-#undef jsimd_ycc_rgb_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define RGB_INDEX \
-  {  0,  1,  8,  9,  2,  3, 10, 11,  4,  5, 12, 13,  6,  7, 14, 15 }
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extrgbx_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_ycc_rgb_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define RGB_INDEX0 \
-  {  8,  1,  0, 10,  3,  2, 12,  5,  4, 14,  7,  6, 24, 17, 16, 26 }
-#define RGB_INDEX1 \
-  {  3,  2, 12,  5,  4, 14,  7,  6, 24, 17, 16, 26, 19, 18, 28, 21 }
-#define RGB_INDEX2 \
-  {  4, 14,  7,  6, 24, 17, 16, 26, 19, 18, 28, 21, 20, 30, 23, 22 }
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extbgr_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX0
-#undef RGB_INDEX1
-#undef RGB_INDEX2
-#undef jsimd_ycc_rgb_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define RGB_INDEX \
-  {  8,  1,  0,  9, 10,  3,  2, 11, 12,  5,  4, 13, 14,  7,  6, 15 }
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extbgrx_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_ycc_rgb_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define RGB_INDEX \
-  {  9,  8,  1,  0, 11, 10,  3,  2, 13, 12,  5,  4, 15, 14,  7,  6 }
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extxbgr_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_ycc_rgb_convert_altivec
-
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define RGB_INDEX \
-  {  9,  0,  1,  8, 11,  2,  3, 10, 13,  4,  5, 12, 15,  6,  7, 14 }
-#define jsimd_ycc_rgb_convert_altivec  jsimd_ycc_extxrgb_convert_altivec
-#include "jdcolext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_ycc_rgb_convert_altivec
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jdmerge-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jdmerge-altivec.c
deleted file mode 100644
index 79c577f..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jdmerge-altivec.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* MERGED YCC --> RGB CONVERSION AND UPSAMPLING */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_344  22554              /* FIX(0.34414) */
-#define F_0_714  46802              /* FIX(0.71414) */
-#define F_1_402  91881              /* FIX(1.40200) */
-#define F_1_772  116130             /* FIX(1.77200) */
-#define F_0_402  (F_1_402 - 65536)  /* FIX(1.40200) - FIX(1) */
-#define F_0_285  (65536 - F_0_714)  /* FIX(1) - FIX(0.71414) */
-#define F_0_228  (131072 - F_1_772) /* FIX(2) - FIX(1.77200) */
-
-#define SCALEBITS  16
-#define ONE_HALF  (1 << (SCALEBITS - 1))
-
-#define RGB_INDEX0 \
-  {  0,  1,  8,  2,  3, 10,  4,  5, 12,  6,  7, 14, 16, 17, 24, 18 }
-#define RGB_INDEX1 \
-  {  3, 10,  4,  5, 12,  6,  7, 14, 16, 17, 24, 18, 19, 26, 20, 21 }
-#define RGB_INDEX2 \
-  { 12,  6,  7, 14, 16, 17, 24, 18, 19, 26, 20, 21, 28, 22, 23, 30 }
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-
-#define RGB_PIXELSIZE  EXT_RGB_PIXELSIZE
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extrgb_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extrgb_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX0
-#undef RGB_INDEX1
-#undef RGB_INDEX2
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
-
-#define RGB_PIXELSIZE  EXT_RGBX_PIXELSIZE
-#define RGB_INDEX \
-  {  0,  1,  8,  9,  2,  3, 10, 11,  4,  5, 12, 13,  6,  7, 14, 15 }
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extrgbx_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extrgbx_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
-
-#define RGB_PIXELSIZE  EXT_BGR_PIXELSIZE
-#define RGB_INDEX0 \
-  {  8,  1,  0, 10,  3,  2, 12,  5,  4, 14,  7,  6, 24, 17, 16, 26 }
-#define RGB_INDEX1 \
-  {  3,  2, 12,  5,  4, 14,  7,  6, 24, 17, 16, 26, 19, 18, 28, 21 }
-#define RGB_INDEX2 \
-  {  4, 14,  7,  6, 24, 17, 16, 26, 19, 18, 28, 21, 20, 30, 23, 22 }
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extbgr_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extbgr_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX0
-#undef RGB_INDEX1
-#undef RGB_INDEX2
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
-
-#define RGB_PIXELSIZE  EXT_BGRX_PIXELSIZE
-#define RGB_INDEX \
-  {  8,  1,  0,  9, 10,  3,  2, 11, 12,  5,  4, 13, 14,  7,  6, 15 }
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extbgrx_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extbgrx_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
-
-#define RGB_PIXELSIZE  EXT_XBGR_PIXELSIZE
-#define RGB_INDEX \
-  {  9,  8,  1,  0, 11, 10,  3,  2, 13, 12,  5,  4, 15, 14,  7,  6 }
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extxbgr_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extxbgr_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
-
-#define RGB_PIXELSIZE  EXT_XRGB_PIXELSIZE
-#define RGB_INDEX \
-  {  9,  0,  1,  8, 11,  2,  3, 10, 13,  4,  5, 12, 15,  6,  7, 14 }
-#define jsimd_h2v1_merged_upsample_altivec \
-  jsimd_h2v1_extxrgb_merged_upsample_altivec
-#define jsimd_h2v2_merged_upsample_altivec \
-  jsimd_h2v2_extxrgb_merged_upsample_altivec
-#include "jdmrgext-altivec.c"
-#undef RGB_PIXELSIZE
-#undef RGB_INDEX
-#undef jsimd_h2v1_merged_upsample_altivec
-#undef jsimd_h2v2_merged_upsample_altivec
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jdmrgext-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jdmrgext-altivec.c
deleted file mode 100644
index 40f02c3..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jdmrgext-altivec.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* This file is included by jdmerge-altivec.c */
-
-
-void jsimd_h2v1_merged_upsample_altivec(JDIMENSION output_width,
-                                        JSAMPIMAGE input_buf,
-                                        JDIMENSION in_row_group_ctr,
-                                        JSAMPARRAY output_buf)
-{
-  JSAMPROW outptr, inptr0, inptr1, inptr2;
-  int pitch = output_width * RGB_PIXELSIZE, num_cols, yloop;
-#if __BIG_ENDIAN__
-  int offset;
-#endif
-  unsigned char __attribute__((aligned(16))) tmpbuf[RGB_PIXELSIZE * 16];
-
-  __vector unsigned char rgb0, rgb1, rgb2, rgbx0, rgbx1, rgbx2, rgbx3,
-    y, cb, cr;
-#if __BIG_ENDIAN__
-  __vector unsigned char edgel, edgeh, edges, out0, out1, out2, out3;
-#if RGB_PIXELSIZE == 4
-  __vector unsigned char out4;
-#endif
-#endif
-#if RGB_PIXELSIZE == 4
-  __vector unsigned char rgb3;
-#endif
-  __vector short rg0, rg1, rg2, rg3, bx0, bx1, bx2, bx3, ye, yo, cbl, cbh,
-    crl, crh, r_yl, r_yh, g_yl, g_yh, b_yl, b_yh, g_y0w, g_y1w, g_y2w, g_y3w,
-    rl, rh, gl, gh, bl, bh, re, ro, ge, go, be, bo;
-  __vector int g_y0, g_y1, g_y2, g_y3;
-
-  /* Constants
-   * NOTE: The >> 1 is to compensate for the fact that vec_madds() returns 17
-   * high-order bits, not 16.
-   */
-  __vector short pw_f0402 = { __8X(F_0_402 >> 1) },
-    pw_mf0228 = { __8X(-F_0_228 >> 1) },
-    pw_mf0344_f0285 = { __4X2(-F_0_344, F_0_285) },
-    pw_one = { __8X(1) }, pw_255 = { __8X(255) },
-    pw_cj = { __8X(CENTERJSAMPLE) };
-  __vector int pd_onehalf = { __4X(ONE_HALF) };
-  __vector unsigned char pb_zero = { __16X(0) },
-#if __BIG_ENDIAN__
-    shift_pack_index =
-      {  0,  1,  4,  5,  8,  9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 },
-    even_index =
-      {  0, 16,  0, 18,  0, 20,  0, 22,  0, 24,  0, 26,  0, 28,  0, 30 },
-    odd_index =
-      {  0, 17,  0, 19,  0, 21,  0, 23,  0, 25,  0, 27,  0, 29,  0, 31 };
-#else
-    shift_pack_index =
-      {  2,  3,  6,  7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 },
-    even_index =
-      { 16,  0, 18,  0, 20,  0, 22,  0, 24,  0, 26,  0, 28,  0, 30,  0 },
-    odd_index =
-      { 17,  0, 19,  0, 21,  0, 23,  0, 25,  0, 27,  0, 29,  0, 31,  0 };
-#endif
-
-  inptr0 = input_buf[0][in_row_group_ctr];
-  inptr1 = input_buf[1][in_row_group_ctr];
-  inptr2 = input_buf[2][in_row_group_ctr];
-  outptr = output_buf[0];
-
-  for (num_cols = pitch; num_cols > 0; inptr1 += 16, inptr2 += 16) {
-
-    cb = vec_ld(0, inptr1);
-    /* NOTE: We have to use vec_merge*() here because vec_unpack*() doesn't
-     * support unsigned vectors.
-     */
-    cbl = (__vector signed short)VEC_UNPACKHU(cb);
-    cbh = (__vector signed short)VEC_UNPACKLU(cb);
-    cbl = vec_sub(cbl, pw_cj);
-    cbh = vec_sub(cbh, pw_cj);
-
-    cr = vec_ld(0, inptr2);
-    crl = (__vector signed short)VEC_UNPACKHU(cr);
-    crh = (__vector signed short)VEC_UNPACKLU(cr);
-    crl = vec_sub(crl, pw_cj);
-    crh = vec_sub(crh, pw_cj);
-
-    /* (Original)
-     * R = Y                + 1.40200 * Cr
-     * G = Y - 0.34414 * Cb - 0.71414 * Cr
-     * B = Y + 1.77200 * Cb
-     *
-     * (This implementation)
-     * R = Y                + 0.40200 * Cr + Cr
-     * G = Y - 0.34414 * Cb + 0.28586 * Cr - Cr
-     * B = Y - 0.22800 * Cb + Cb + Cb
-     */
-    b_yl = vec_add(cbl, cbl);
-    b_yh = vec_add(cbh, cbh);
-    b_yl = vec_madds(b_yl, pw_mf0228, pw_one);
-    b_yh = vec_madds(b_yh, pw_mf0228, pw_one);
-    b_yl = vec_sra(b_yl, (__vector unsigned short)pw_one);
-    b_yh = vec_sra(b_yh, (__vector unsigned short)pw_one);
-    b_yl = vec_add(b_yl, cbl);
-    b_yh = vec_add(b_yh, cbh);
-    b_yl = vec_add(b_yl, cbl);
-    b_yh = vec_add(b_yh, cbh);
-
-    r_yl = vec_add(crl, crl);
-    r_yh = vec_add(crh, crh);
-    r_yl = vec_madds(r_yl, pw_f0402, pw_one);
-    r_yh = vec_madds(r_yh, pw_f0402, pw_one);
-    r_yl = vec_sra(r_yl, (__vector unsigned short)pw_one);
-    r_yh = vec_sra(r_yh, (__vector unsigned short)pw_one);
-    r_yl = vec_add(r_yl, crl);
-    r_yh = vec_add(r_yh, crh);
-
-    g_y0w = vec_mergeh(cbl, crl);
-    g_y1w = vec_mergel(cbl, crl);
-    g_y0 = vec_msums(g_y0w, pw_mf0344_f0285, pd_onehalf);
-    g_y1 = vec_msums(g_y1w, pw_mf0344_f0285, pd_onehalf);
-    g_y2w = vec_mergeh(cbh, crh);
-    g_y3w = vec_mergel(cbh, crh);
-    g_y2 = vec_msums(g_y2w, pw_mf0344_f0285, pd_onehalf);
-    g_y3 = vec_msums(g_y3w, pw_mf0344_f0285, pd_onehalf);
-    /* Clever way to avoid 4 shifts + 2 packs.  This packs the high word from
-     * each dword into a new 16-bit vector, which is the equivalent of
-     * descaling the 32-bit results (right-shifting by 16 bits) and then
-     * packing them.
-     */
-    g_yl = vec_perm((__vector short)g_y0, (__vector short)g_y1,
-                    shift_pack_index);
-    g_yh = vec_perm((__vector short)g_y2, (__vector short)g_y3,
-                    shift_pack_index);
-    g_yl = vec_sub(g_yl, crl);
-    g_yh = vec_sub(g_yh, crh);
-
-    for (yloop = 0; yloop < 2 && num_cols > 0; yloop++,
-         num_cols -= RGB_PIXELSIZE * 16,
-         outptr += RGB_PIXELSIZE * 16, inptr0 += 16) {
-
-      y = vec_ld(0, inptr0);
-      ye = (__vector signed short)vec_perm(pb_zero, y, even_index);
-      yo = (__vector signed short)vec_perm(pb_zero, y, odd_index);
-
-      if (yloop == 0) {
-        be = vec_add(b_yl, ye);
-        bo = vec_add(b_yl, yo);
-        re = vec_add(r_yl, ye);
-        ro = vec_add(r_yl, yo);
-        ge = vec_add(g_yl, ye);
-        go = vec_add(g_yl, yo);
-      } else {
-        be = vec_add(b_yh, ye);
-        bo = vec_add(b_yh, yo);
-        re = vec_add(r_yh, ye);
-        ro = vec_add(r_yh, yo);
-        ge = vec_add(g_yh, ye);
-        go = vec_add(g_yh, yo);
-      }
-
-      rl = vec_mergeh(re, ro);
-      rh = vec_mergel(re, ro);
-      gl = vec_mergeh(ge, go);
-      gh = vec_mergel(ge, go);
-      bl = vec_mergeh(be, bo);
-      bh = vec_mergel(be, bo);
-
-      rg0 = vec_mergeh(rl, gl);
-      bx0 = vec_mergeh(bl, pw_255);
-      rg1 = vec_mergel(rl, gl);
-      bx1 = vec_mergel(bl, pw_255);
-      rg2 = vec_mergeh(rh, gh);
-      bx2 = vec_mergeh(bh, pw_255);
-      rg3 = vec_mergel(rh, gh);
-      bx3 = vec_mergel(bh, pw_255);
-
-      rgbx0 = vec_packsu(rg0, bx0);
-      rgbx1 = vec_packsu(rg1, bx1);
-      rgbx2 = vec_packsu(rg2, bx2);
-      rgbx3 = vec_packsu(rg3, bx3);
-
-#if RGB_PIXELSIZE == 3
-      /* rgbx0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 X0 B1 X1 B2 X2 B3 X3
-       * rgbx1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 X4 B5 X5 B6 X6 B7 X7
-       * rgbx2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 X8 B9 X9 Ba Xa Bb Xb
-       * rgbx3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Xc Bd Xd Be Xe Bf Xf
-       *
-       * rgb0 = R0 G0 B0 R1 G1 B1 R2 G2 B2 R3 G3 B3 R4 G4 B4 R5
-       * rgb1 = G5 B5 R6 G6 B6 R7 G7 B7 R8 G8 B8 R9 G9 B9 Ra Ga
-       * rgb2 = Ba Rb Gb Bb Rc Gc Bc Rd Gd Bd Re Ge Be Rf Gf Bf
-       */
-      rgb0 = vec_perm(rgbx0, rgbx1, (__vector unsigned char)RGB_INDEX0);
-      rgb1 = vec_perm(rgbx1, rgbx2, (__vector unsigned char)RGB_INDEX1);
-      rgb2 = vec_perm(rgbx2, rgbx3, (__vector unsigned char)RGB_INDEX2);
-#else
-      /* rgbx0 = R0 G0 R1 G1 R2 G2 R3 G3 B0 X0 B1 X1 B2 X2 B3 X3
-       * rgbx1 = R4 G4 R5 G5 R6 G6 R7 G7 B4 X4 B5 X5 B6 X6 B7 X7
-       * rgbx2 = R8 G8 R9 G9 Ra Ga Rb Gb B8 X8 B9 X9 Ba Xa Bb Xb
-       * rgbx3 = Rc Gc Rd Gd Re Ge Rf Gf Bc Xc Bd Xd Be Xe Bf Xf
-       *
-       * rgb0 = R0 G0 B0 X0 R1 G1 B1 X1 R2 G2 B2 X2 R3 G3 B3 X3
-       * rgb1 = R4 G4 B4 X4 R5 G5 B5 X5 R6 G6 B6 X6 R7 G7 B7 X7
-       * rgb2 = R8 G8 B8 X8 R9 G9 B9 X9 Ra Ga Ba Xa Rb Gb Bb Xb
-       * rgb3 = Rc Gc Bc Xc Rd Gd Bd Xd Re Ge Be Xe Rf Gf Bf Xf
-       */
-      rgb0 = vec_perm(rgbx0, rgbx0, (__vector unsigned char)RGB_INDEX);
-      rgb1 = vec_perm(rgbx1, rgbx1, (__vector unsigned char)RGB_INDEX);
-      rgb2 = vec_perm(rgbx2, rgbx2, (__vector unsigned char)RGB_INDEX);
-      rgb3 = vec_perm(rgbx3, rgbx3, (__vector unsigned char)RGB_INDEX);
-#endif
-
-#if __BIG_ENDIAN__
-      offset = (size_t)outptr & 15;
-      if (offset) {
-        __vector unsigned char unaligned_shift_index;
-        int bytes = num_cols + offset;
-
-        if (bytes < (RGB_PIXELSIZE + 1) * 16 && (bytes & 15)) {
-          /* Slow path to prevent buffer overwrite.  Since there is no way to
-           * write a partial AltiVec register, overwrite would occur on the
-           * last chunk of the last image row if the right edge is not on a
-           * 16-byte boundary.  It could also occur on other rows if the bytes
-           * per row is low enough.  Since we can't determine whether we're on
-           * the last image row, we have to assume every row is the last.
-           */
-          vec_st(rgb0, 0, tmpbuf);
-          vec_st(rgb1, 16, tmpbuf);
-          vec_st(rgb2, 32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          vec_st(rgb3, 48, tmpbuf);
-#endif
-          memcpy(outptr, tmpbuf, min(num_cols, RGB_PIXELSIZE * 16));
-        } else {
-          /* Fast path */
-          unaligned_shift_index = vec_lvsl(0, outptr);
-          edgel = vec_ld(0, outptr);
-          edgeh = vec_ld(min(num_cols - 1, RGB_PIXELSIZE * 16), outptr);
-          edges = vec_perm(edgeh, edgel, unaligned_shift_index);
-          unaligned_shift_index = vec_lvsr(0, outptr);
-          out0 = vec_perm(edges, rgb0, unaligned_shift_index);
-          out1 = vec_perm(rgb0, rgb1, unaligned_shift_index);
-          out2 = vec_perm(rgb1, rgb2, unaligned_shift_index);
-#if RGB_PIXELSIZE == 4
-          out3 = vec_perm(rgb2, rgb3, unaligned_shift_index);
-          out4 = vec_perm(rgb3, edges, unaligned_shift_index);
-#else
-          out3 = vec_perm(rgb2, edges, unaligned_shift_index);
-#endif
-          vec_st(out0, 0, outptr);
-          if (bytes > 16)
-            vec_st(out1, 16, outptr);
-          if (bytes > 32)
-            vec_st(out2, 32, outptr);
-          if (bytes > 48)
-            vec_st(out3, 48, outptr);
-#if RGB_PIXELSIZE == 4
-          if (bytes > 64)
-            vec_st(out4, 64, outptr);
-#endif
-        }
-      } else {
-#endif /* __BIG_ENDIAN__ */
-        if (num_cols < RGB_PIXELSIZE * 16 && (num_cols & 15)) {
-          /* Slow path */
-          VEC_ST(rgb0, 0, tmpbuf);
-          VEC_ST(rgb1, 16, tmpbuf);
-          VEC_ST(rgb2, 32, tmpbuf);
-#if RGB_PIXELSIZE == 4
-          VEC_ST(rgb3, 48, tmpbuf);
-#endif
-          memcpy(outptr, tmpbuf, min(num_cols, RGB_PIXELSIZE * 16));
-        } else {
-          /* Fast path */
-          VEC_ST(rgb0, 0, outptr);
-          if (num_cols > 16)
-            VEC_ST(rgb1, 16, outptr);
-          if (num_cols > 32)
-            VEC_ST(rgb2, 32, outptr);
-#if RGB_PIXELSIZE == 4
-          if (num_cols > 48)
-            VEC_ST(rgb3, 48, outptr);
-#endif
-        }
-#if __BIG_ENDIAN__
-      }
-#endif
-    }
-  }
-}
-
-
-void jsimd_h2v2_merged_upsample_altivec(JDIMENSION output_width,
-                                        JSAMPIMAGE input_buf,
-                                        JDIMENSION in_row_group_ctr,
-                                        JSAMPARRAY output_buf)
-{
-  JSAMPROW inptr, outptr;
-
-  inptr = input_buf[0][in_row_group_ctr];
-  outptr = output_buf[0];
-
-  input_buf[0][in_row_group_ctr] = input_buf[0][in_row_group_ctr * 2];
-  jsimd_h2v1_merged_upsample_altivec(output_width, input_buf, in_row_group_ctr,
-                                     output_buf);
-
-  input_buf[0][in_row_group_ctr] = input_buf[0][in_row_group_ctr * 2 + 1];
-  output_buf[0] = output_buf[1];
-  jsimd_h2v1_merged_upsample_altivec(output_width, input_buf, in_row_group_ctr,
-                                     output_buf);
-
-  input_buf[0][in_row_group_ctr] = inptr;
-  output_buf[0] = outptr;
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jdsample-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jdsample-altivec.c
deleted file mode 100644
index 04df0cf..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jdsample-altivec.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* CHROMA UPSAMPLING */
-
-#include "jsimd_altivec.h"
-
-
-void jsimd_h2v1_fancy_upsample_altivec(int max_v_samp_factor,
-                                       JDIMENSION downsampled_width,
-                                       JSAMPARRAY input_data,
-                                       JSAMPARRAY *output_data_ptr)
-{
-  JSAMPARRAY output_data = *output_data_ptr;
-  JSAMPROW inptr, outptr;
-  int inrow, incol;
-
-  __vector unsigned char this0, last0, p_last0, next0 = { 0 }, p_next0,
-    out;
-  __vector short this0e, this0o, this0l, this0h, last0l, last0h,
-    next0l, next0h, outle, outhe, outlo, outho;
-
-  /* Constants */
-  __vector unsigned char pb_zero = { __16X(0) }, pb_three = { __16X(3) },
-    last_index_col0 =
-      {  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14 },
-    last_index =
-      { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
-    next_index =
-      {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16 },
-    next_index_lastcol =
-      {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 15 },
-#if __BIG_ENDIAN__
-    merge_pack_index =
-      {  1, 17,  3, 19,  5, 21,  7, 23,  9, 25, 11, 27, 13, 29, 15, 31 };
-#else
-    merge_pack_index =
-      {  0, 16,  2, 18,  4, 20,  6, 22,  8, 24, 10, 26, 12, 28, 14, 30 };
-#endif
-  __vector short pw_one = { __8X(1) }, pw_two = { __8X(2) };
-
-  for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
-    inptr = input_data[inrow];
-    outptr = output_data[inrow];
-
-    if (downsampled_width & 15)
-      inptr[downsampled_width] = inptr[downsampled_width - 1];
-
-    this0 = vec_ld(0, inptr);
-    p_last0 = vec_perm(this0, this0, last_index_col0);
-    last0 = this0;
-
-    for (incol = downsampled_width; incol > 0;
-         incol -= 16, inptr += 16, outptr += 32) {
-
-      if (downsampled_width - incol > 0) {
-        p_last0 = vec_perm(last0, this0, last_index);
-        last0 = this0;
-      }
-
-      if (incol <= 16)
-        p_next0 = vec_perm(this0, this0, next_index_lastcol);
-      else {
-        next0 = vec_ld(16, inptr);
-        p_next0 = vec_perm(this0, next0, next_index);
-      }
-
-      this0e = (__vector short)vec_mule(this0, pb_three);
-      this0o = (__vector short)vec_mulo(this0, pb_three);
-      this0l = vec_mergeh(this0e, this0o);
-      this0h = vec_mergel(this0e, this0o);
-
-      last0l = (__vector short)VEC_UNPACKHU(p_last0);
-      last0h = (__vector short)VEC_UNPACKLU(p_last0);
-      last0l = vec_add(last0l, pw_one);
-
-      next0l = (__vector short)VEC_UNPACKHU(p_next0);
-      next0h = (__vector short)VEC_UNPACKLU(p_next0);
-      next0l = vec_add(next0l, pw_two);
-
-      outle = vec_add(this0l, last0l);
-      outlo = vec_add(this0l, next0l);
-      outle = vec_sr(outle, (__vector unsigned short)pw_two);
-      outlo = vec_sr(outlo, (__vector unsigned short)pw_two);
-
-      out = vec_perm((__vector unsigned char)outle,
-                     (__vector unsigned char)outlo, merge_pack_index);
-      vec_st(out, 0, outptr);
-
-      if (incol > 8) {
-        last0h = vec_add(last0h, pw_one);
-        next0h = vec_add(next0h, pw_two);
-
-        outhe = vec_add(this0h, last0h);
-        outho = vec_add(this0h, next0h);
-        outhe = vec_sr(outhe, (__vector unsigned short)pw_two);
-        outho = vec_sr(outho, (__vector unsigned short)pw_two);
-
-        out = vec_perm((__vector unsigned char)outhe,
-                       (__vector unsigned char)outho, merge_pack_index);
-        vec_st(out, 16, outptr);
-      }
-
-      this0 = next0;
-    }
-  }
-}
-
-
-void jsimd_h2v2_fancy_upsample_altivec(int max_v_samp_factor,
-                                       JDIMENSION downsampled_width,
-                                       JSAMPARRAY input_data,
-                                       JSAMPARRAY *output_data_ptr)
-{
-  JSAMPARRAY output_data = *output_data_ptr;
-  JSAMPROW inptr_1, inptr0, inptr1, outptr0, outptr1;
-  int inrow, outrow, incol;
-
-  __vector unsigned char this_1, this0, this1, out;
-  __vector short this_1l, this_1h, this0l, this0h, this1l, this1h,
-    lastcolsum_1h, lastcolsum1h,
-    p_lastcolsum_1l, p_lastcolsum_1h, p_lastcolsum1l, p_lastcolsum1h,
-    thiscolsum_1l, thiscolsum_1h, thiscolsum1l, thiscolsum1h,
-    nextcolsum_1l = { 0 }, nextcolsum_1h = { 0 },
-    nextcolsum1l = { 0 }, nextcolsum1h = { 0 },
-    p_nextcolsum_1l, p_nextcolsum_1h, p_nextcolsum1l, p_nextcolsum1h,
-    tmpl, tmph, outle, outhe, outlo, outho;
-
-  /* Constants */
-  __vector unsigned char pb_zero = { __16X(0) },
-    last_index_col0 =
-      {  0,  1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13 },
-    last_index =
-      { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 },
-    next_index =
-      {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17 },
-    next_index_lastcol =
-      {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 14, 15 },
-#if __BIG_ENDIAN__
-    merge_pack_index =
-      {  1, 17,  3, 19,  5, 21,  7, 23,  9, 25, 11, 27, 13, 29, 15, 31 };
-#else
-    merge_pack_index =
-      {  0, 16,  2, 18,  4, 20,  6, 22,  8, 24, 10, 26, 12, 28, 14, 30 };
-#endif
-  __vector short pw_zero = { __8X(0) }, pw_three = { __8X(3) },
-    pw_seven = { __8X(7) }, pw_eight = { __8X(8) };
-  __vector unsigned short pw_four = { __8X(4) };
-
-  for (inrow = 0, outrow = 0; outrow < max_v_samp_factor; inrow++) {
-
-    inptr_1 = input_data[inrow - 1];
-    inptr0 = input_data[inrow];
-    inptr1 = input_data[inrow + 1];
-    outptr0 = output_data[outrow++];
-    outptr1 = output_data[outrow++];
-
-    if (downsampled_width & 15) {
-      inptr_1[downsampled_width] = inptr_1[downsampled_width - 1];
-      inptr0[downsampled_width] = inptr0[downsampled_width - 1];
-      inptr1[downsampled_width] = inptr1[downsampled_width - 1];
-    }
-
-    this0 = vec_ld(0, inptr0);
-    this0l = (__vector short)VEC_UNPACKHU(this0);
-    this0h = (__vector short)VEC_UNPACKLU(this0);
-    this0l = vec_mladd(this0l, pw_three, pw_zero);
-    this0h = vec_mladd(this0h, pw_three, pw_zero);
-
-    this_1 = vec_ld(0, inptr_1);
-    this_1l = (__vector short)VEC_UNPACKHU(this_1);
-    this_1h = (__vector short)VEC_UNPACKLU(this_1);
-    thiscolsum_1l = vec_add(this0l, this_1l);
-    thiscolsum_1h = vec_add(this0h, this_1h);
-    lastcolsum_1h = thiscolsum_1h;
-    p_lastcolsum_1l = vec_perm(thiscolsum_1l, thiscolsum_1l, last_index_col0);
-    p_lastcolsum_1h = vec_perm(thiscolsum_1l, thiscolsum_1h, last_index);
-
-    this1 = vec_ld(0, inptr1);
-    this1l = (__vector short)VEC_UNPACKHU(this1);
-    this1h = (__vector short)VEC_UNPACKLU(this1);
-    thiscolsum1l = vec_add(this0l, this1l);
-    thiscolsum1h = vec_add(this0h, this1h);
-    lastcolsum1h = thiscolsum1h;
-    p_lastcolsum1l = vec_perm(thiscolsum1l, thiscolsum1l, last_index_col0);
-    p_lastcolsum1h = vec_perm(thiscolsum1l, thiscolsum1h, last_index);
-
-    for (incol = downsampled_width; incol > 0;
-         incol -= 16, inptr_1 += 16, inptr0 += 16, inptr1 += 16,
-         outptr0 += 32, outptr1 += 32) {
-
-      if (downsampled_width - incol > 0) {
-        p_lastcolsum_1l = vec_perm(lastcolsum_1h, thiscolsum_1l, last_index);
-        p_lastcolsum_1h = vec_perm(thiscolsum_1l, thiscolsum_1h, last_index);
-        p_lastcolsum1l = vec_perm(lastcolsum1h, thiscolsum1l, last_index);
-        p_lastcolsum1h = vec_perm(thiscolsum1l, thiscolsum1h, last_index);
-        lastcolsum_1h = thiscolsum_1h;  lastcolsum1h = thiscolsum1h;
-      }
-
-      if (incol <= 16) {
-        p_nextcolsum_1l = vec_perm(thiscolsum_1l, thiscolsum_1h, next_index);
-        p_nextcolsum_1h = vec_perm(thiscolsum_1h, thiscolsum_1h,
-                                   next_index_lastcol);
-        p_nextcolsum1l = vec_perm(thiscolsum1l, thiscolsum1h, next_index);
-        p_nextcolsum1h = vec_perm(thiscolsum1h, thiscolsum1h,
-                                  next_index_lastcol);
-      } else {
-        this0 = vec_ld(16, inptr0);
-        this0l = (__vector short)VEC_UNPACKHU(this0);
-        this0h = (__vector short)VEC_UNPACKLU(this0);
-        this0l = vec_mladd(this0l, pw_three, pw_zero);
-        this0h = vec_mladd(this0h, pw_three, pw_zero);
-
-        this_1 = vec_ld(16, inptr_1);
-        this_1l = (__vector short)VEC_UNPACKHU(this_1);
-        this_1h = (__vector short)VEC_UNPACKLU(this_1);
-        nextcolsum_1l = vec_add(this0l, this_1l);
-        nextcolsum_1h = vec_add(this0h, this_1h);
-        p_nextcolsum_1l = vec_perm(thiscolsum_1l, thiscolsum_1h, next_index);
-        p_nextcolsum_1h = vec_perm(thiscolsum_1h, nextcolsum_1l, next_index);
-
-        this1 = vec_ld(16, inptr1);
-        this1l = (__vector short)VEC_UNPACKHU(this1);
-        this1h = (__vector short)VEC_UNPACKLU(this1);
-        nextcolsum1l = vec_add(this0l, this1l);
-        nextcolsum1h = vec_add(this0h, this1h);
-        p_nextcolsum1l = vec_perm(thiscolsum1l, thiscolsum1h, next_index);
-        p_nextcolsum1h = vec_perm(thiscolsum1h, nextcolsum1l, next_index);
-      }
-
-      /* Process the upper row */
-
-      tmpl = vec_mladd(thiscolsum_1l, pw_three, pw_zero);
-      outle = vec_add(tmpl, p_lastcolsum_1l);
-      outle = vec_add(outle, pw_eight);
-      outle = vec_sr(outle, pw_four);
-
-      outlo = vec_add(tmpl, p_nextcolsum_1l);
-      outlo = vec_add(outlo, pw_seven);
-      outlo = vec_sr(outlo, pw_four);
-
-      out = vec_perm((__vector unsigned char)outle,
-                     (__vector unsigned char)outlo, merge_pack_index);
-      vec_st(out, 0, outptr0);
-
-      if (incol > 8) {
-        tmph = vec_mladd(thiscolsum_1h, pw_three, pw_zero);
-        outhe = vec_add(tmph, p_lastcolsum_1h);
-        outhe = vec_add(outhe, pw_eight);
-        outhe = vec_sr(outhe, pw_four);
-
-        outho = vec_add(tmph, p_nextcolsum_1h);
-        outho = vec_add(outho, pw_seven);
-        outho = vec_sr(outho, pw_four);
-
-        out = vec_perm((__vector unsigned char)outhe,
-                       (__vector unsigned char)outho, merge_pack_index);
-        vec_st(out, 16, outptr0);
-      }
-
-      /* Process the lower row */
-
-      tmpl = vec_mladd(thiscolsum1l, pw_three, pw_zero);
-      outle = vec_add(tmpl, p_lastcolsum1l);
-      outle = vec_add(outle, pw_eight);
-      outle = vec_sr(outle, pw_four);
-
-      outlo = vec_add(tmpl, p_nextcolsum1l);
-      outlo = vec_add(outlo, pw_seven);
-      outlo = vec_sr(outlo, pw_four);
-
-      out = vec_perm((__vector unsigned char)outle,
-                     (__vector unsigned char)outlo, merge_pack_index);
-      vec_st(out, 0, outptr1);
-
-      if (incol > 8) {
-        tmph = vec_mladd(thiscolsum1h, pw_three, pw_zero);
-        outhe = vec_add(tmph, p_lastcolsum1h);
-        outhe = vec_add(outhe, pw_eight);
-        outhe = vec_sr(outhe, pw_four);
-
-        outho = vec_add(tmph, p_nextcolsum1h);
-        outho = vec_add(outho, pw_seven);
-        outho = vec_sr(outho, pw_four);
-
-        out = vec_perm((__vector unsigned char)outhe,
-                       (__vector unsigned char)outho, merge_pack_index);
-        vec_st(out, 16, outptr1);
-      }
-
-      thiscolsum_1l = nextcolsum_1l;  thiscolsum_1h = nextcolsum_1h;
-      thiscolsum1l = nextcolsum1l;  thiscolsum1h = nextcolsum1h;
-    }
-  }
-}
-
-
-/* These are rarely used (mainly just for decompressing YCCK images) */
-
-void jsimd_h2v1_upsample_altivec(int max_v_samp_factor,
-                                 JDIMENSION output_width,
-                                 JSAMPARRAY input_data,
-                                 JSAMPARRAY *output_data_ptr)
-{
-  JSAMPARRAY output_data = *output_data_ptr;
-  JSAMPROW inptr, outptr;
-  int inrow, incol;
-
-  __vector unsigned char in, inl, inh;
-
-  for (inrow = 0; inrow < max_v_samp_factor; inrow++) {
-    inptr = input_data[inrow];
-    outptr = output_data[inrow];
-
-    for (incol = (output_width + 31) & (~31); incol > 0;
-         incol -= 64, inptr += 32, outptr += 64) {
-
-      in = vec_ld(0, inptr);
-      inl = vec_mergeh(in, in);
-      inh = vec_mergel(in, in);
-
-      vec_st(inl, 0, outptr);
-      vec_st(inh, 16, outptr);
-
-      if (incol > 32) {
-        in = vec_ld(16, inptr);
-        inl = vec_mergeh(in, in);
-        inh = vec_mergel(in, in);
-
-        vec_st(inl, 32, outptr);
-        vec_st(inh, 48, outptr);
-      }
-    }
-  }
-}
-
-
-void jsimd_h2v2_upsample_altivec(int max_v_samp_factor,
-                                 JDIMENSION output_width,
-                                 JSAMPARRAY input_data,
-                                 JSAMPARRAY *output_data_ptr)
-{
-  JSAMPARRAY output_data = *output_data_ptr;
-  JSAMPROW inptr, outptr0, outptr1;
-  int inrow, outrow, incol;
-
-  __vector unsigned char in, inl, inh;
-
-  for (inrow = 0, outrow = 0; outrow < max_v_samp_factor; inrow++) {
-
-    inptr = input_data[inrow];
-    outptr0 = output_data[outrow++];
-    outptr1 = output_data[outrow++];
-
-    for (incol = (output_width + 31) & (~31); incol > 0;
-         incol -= 64, inptr += 32, outptr0 += 64, outptr1 += 64) {
-
-      in = vec_ld(0, inptr);
-      inl = vec_mergeh(in, in);
-      inh = vec_mergel(in, in);
-
-      vec_st(inl, 0, outptr0);
-      vec_st(inl, 0, outptr1);
-
-      vec_st(inh, 16, outptr0);
-      vec_st(inh, 16, outptr1);
-
-      if (incol > 32) {
-        in = vec_ld(16, inptr);
-        inl = vec_mergeh(in, in);
-        inh = vec_mergel(in, in);
-
-        vec_st(inl, 32, outptr0);
-        vec_st(inl, 32, outptr1);
-
-        vec_st(inh, 48, outptr0);
-        vec_st(inh, 48, outptr1);
-      }
-    }
-  }
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jfdctfst-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jfdctfst-altivec.c
deleted file mode 100644
index ad9af81..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jfdctfst-altivec.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* FAST INTEGER FORWARD DCT
- *
- * This is similar to the SSE2 implementation, except that we left-shift the
- * constants by 1 less bit (the -1 in CONST_SHIFT.)  This is because
- * vec_madds(arg1, arg2, arg3) generates the 16-bit saturated sum of:
- *   the elements in arg3 + the most significant 17 bits of
- *     (the elements in arg1 * the elements in arg2).
- */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_382  98   /* FIX(0.382683433) */
-#define F_0_541  139  /* FIX(0.541196100) */
-#define F_0_707  181  /* FIX(0.707106781) */
-#define F_1_306  334  /* FIX(1.306562965) */
-
-#define CONST_BITS  8
-#define PRE_MULTIPLY_SCALE_BITS  2
-#define CONST_SHIFT  (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS - 1)
-
-
-#define DO_FDCT() { \
-  /* Even part */ \
-  \
-  tmp10 = vec_add(tmp0, tmp3); \
-  tmp13 = vec_sub(tmp0, tmp3); \
-  tmp11 = vec_add(tmp1, tmp2); \
-  tmp12 = vec_sub(tmp1, tmp2); \
-  \
-  out0  = vec_add(tmp10, tmp11); \
-  out4  = vec_sub(tmp10, tmp11); \
-  \
-  z1 = vec_add(tmp12, tmp13); \
-  z1 = vec_sl(z1, pre_multiply_scale_bits); \
-  z1 = vec_madds(z1, pw_0707, pw_zero); \
-  \
-  out2 = vec_add(tmp13, z1); \
-  out6 = vec_sub(tmp13, z1); \
-  \
-  /* Odd part */ \
-  \
-  tmp10 = vec_add(tmp4, tmp5); \
-  tmp11 = vec_add(tmp5, tmp6); \
-  tmp12 = vec_add(tmp6, tmp7); \
-  \
-  tmp10 = vec_sl(tmp10, pre_multiply_scale_bits); \
-  tmp12 = vec_sl(tmp12, pre_multiply_scale_bits); \
-  z5 = vec_sub(tmp10, tmp12); \
-  z5 = vec_madds(z5, pw_0382, pw_zero); \
-  \
-  z2 = vec_madds(tmp10, pw_0541, z5); \
-  z4 = vec_madds(tmp12, pw_1306, z5); \
-  \
-  tmp11 = vec_sl(tmp11, pre_multiply_scale_bits); \
-  z3 = vec_madds(tmp11, pw_0707, pw_zero); \
-  \
-  z11 = vec_add(tmp7, z3); \
-  z13 = vec_sub(tmp7, z3); \
-  \
-  out5 = vec_add(z13, z2); \
-  out3 = vec_sub(z13, z2); \
-  out1 = vec_add(z11, z4); \
-  out7 = vec_sub(z11, z4); \
-}
-
-
-void jsimd_fdct_ifast_altivec(DCTELEM *data)
-{
-  __vector short row0, row1, row2, row3, row4, row5, row6, row7,
-    col0, col1, col2, col3, col4, col5, col6, col7,
-    tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp10, tmp11, tmp12, tmp13,
-    z1, z2, z3, z4, z5, z11, z13,
-    out0, out1, out2, out3, out4, out5, out6, out7;
-
-  /* Constants */
-  __vector short pw_zero = { __8X(0) },
-    pw_0382 = { __8X(F_0_382 << CONST_SHIFT) },
-    pw_0541 = { __8X(F_0_541 << CONST_SHIFT) },
-    pw_0707 = { __8X(F_0_707 << CONST_SHIFT) },
-    pw_1306 = { __8X(F_1_306 << CONST_SHIFT) };
-  __vector unsigned short
-    pre_multiply_scale_bits = { __8X(PRE_MULTIPLY_SCALE_BITS) };
-
-  /* Pass 1: process rows */
-
-  row0 = vec_ld(0, data);
-  row1 = vec_ld(16, data);
-  row2 = vec_ld(32, data);
-  row3 = vec_ld(48, data);
-  row4 = vec_ld(64, data);
-  row5 = vec_ld(80, data);
-  row6 = vec_ld(96, data);
-  row7 = vec_ld(112, data);
-
-  TRANSPOSE(row, col);
-
-  tmp0 = vec_add(col0, col7);
-  tmp7 = vec_sub(col0, col7);
-  tmp1 = vec_add(col1, col6);
-  tmp6 = vec_sub(col1, col6);
-  tmp2 = vec_add(col2, col5);
-  tmp5 = vec_sub(col2, col5);
-  tmp3 = vec_add(col3, col4);
-  tmp4 = vec_sub(col3, col4);
-
-  DO_FDCT();
-
-  /* Pass 2: process columns */
-
-  TRANSPOSE(out, row);
-
-  tmp0 = vec_add(row0, row7);
-  tmp7 = vec_sub(row0, row7);
-  tmp1 = vec_add(row1, row6);
-  tmp6 = vec_sub(row1, row6);
-  tmp2 = vec_add(row2, row5);
-  tmp5 = vec_sub(row2, row5);
-  tmp3 = vec_add(row3, row4);
-  tmp4 = vec_sub(row3, row4);
-
-  DO_FDCT();
-
-  vec_st(out0, 0, data);
-  vec_st(out1, 16, data);
-  vec_st(out2, 32, data);
-  vec_st(out3, 48, data);
-  vec_st(out4, 64, data);
-  vec_st(out5, 80, data);
-  vec_st(out6, 96, data);
-  vec_st(out7, 112, data);
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jfdctint-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jfdctint-altivec.c
deleted file mode 100644
index 6e63cc1..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jfdctint-altivec.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* SLOW INTEGER FORWARD DCT */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_298  2446   /* FIX(0.298631336) */
-#define F_0_390  3196   /* FIX(0.390180644) */
-#define F_0_541  4433   /* FIX(0.541196100) */
-#define F_0_765  6270   /* FIX(0.765366865) */
-#define F_0_899  7373   /* FIX(0.899976223) */
-#define F_1_175  9633   /* FIX(1.175875602) */
-#define F_1_501  12299  /* FIX(1.501321110) */
-#define F_1_847  15137  /* FIX(1.847759065) */
-#define F_1_961  16069  /* FIX(1.961570560) */
-#define F_2_053  16819  /* FIX(2.053119869) */
-#define F_2_562  20995  /* FIX(2.562915447) */
-#define F_3_072  25172  /* FIX(3.072711026) */
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
-#define DESCALE_P2  (CONST_BITS + PASS1_BITS)
-
-
-#define DO_FDCT_COMMON(PASS) { \
-  /* (Original) \
-   * z1 = (tmp12 + tmp13) * 0.541196100; \
-   * data2 = z1 + tmp13 * 0.765366865; \
-   * data6 = z1 + tmp12 * -1.847759065; \
-   * \
-   * (This implementation) \
-   * data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100; \
-   * data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065); \
-   */ \
-  \
-  tmp1312l = vec_mergeh(tmp13, tmp12); \
-  tmp1312h = vec_mergel(tmp13, tmp12); \
-  \
-  out2l = vec_msums(tmp1312l, pw_f130_f054, pd_descale_p##PASS); \
-  out2h = vec_msums(tmp1312h, pw_f130_f054, pd_descale_p##PASS); \
-  out6l = vec_msums(tmp1312l, pw_f054_mf130, pd_descale_p##PASS); \
-  out6h = vec_msums(tmp1312h, pw_f054_mf130, pd_descale_p##PASS); \
-  \
-  out2l = vec_sra(out2l, descale_p##PASS); \
-  out2h = vec_sra(out2h, descale_p##PASS); \
-  out6l = vec_sra(out6l, descale_p##PASS); \
-  out6h = vec_sra(out6h, descale_p##PASS); \
-  \
-  out2 = vec_pack(out2l, out2h); \
-  out6 = vec_pack(out6l, out6h); \
-  \
-  /* Odd part */ \
-  \
-  z3 = vec_add(tmp4, tmp6); \
-  z4 = vec_add(tmp5, tmp7); \
-  \
-  /* (Original) \
-   * z5 = (z3 + z4) * 1.175875602; \
-   * z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644; \
-   * z3 += z5;  z4 += z5; \
-   * \
-   * (This implementation) \
-   * z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602; \
-   * z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644); \
-   */ \
-  \
-  z34l = vec_mergeh(z3, z4); \
-  z34h = vec_mergel(z3, z4); \
-  \
-  z3l = vec_msums(z34l, pw_mf078_f117, pd_descale_p##PASS); \
-  z3h = vec_msums(z34h, pw_mf078_f117, pd_descale_p##PASS); \
-  z4l = vec_msums(z34l, pw_f117_f078, pd_descale_p##PASS); \
-  z4h = vec_msums(z34h, pw_f117_f078, pd_descale_p##PASS); \
-  \
-  /* (Original) \
-   * z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6; \
-   * tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869; \
-   * tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110; \
-   * z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447; \
-   * data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4; \
-   * data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4; \
-   * \
-   * (This implementation) \
-   * tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223; \
-   * tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447; \
-   * tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447); \
-   * tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223); \
-   * data7 = tmp4 + z3;  data5 = tmp5 + z4; \
-   * data3 = tmp6 + z3;  data1 = tmp7 + z4; \
-   */ \
-  \
-  tmp47l = vec_mergeh(tmp4, tmp7); \
-  tmp47h = vec_mergel(tmp4, tmp7); \
-  \
-  out7l = vec_msums(tmp47l, pw_mf060_mf089, z3l); \
-  out7h = vec_msums(tmp47h, pw_mf060_mf089, z3h); \
-  out1l = vec_msums(tmp47l, pw_mf089_f060, z4l); \
-  out1h = vec_msums(tmp47h, pw_mf089_f060, z4h); \
-  \
-  out7l = vec_sra(out7l, descale_p##PASS); \
-  out7h = vec_sra(out7h, descale_p##PASS); \
-  out1l = vec_sra(out1l, descale_p##PASS); \
-  out1h = vec_sra(out1h, descale_p##PASS); \
-  \
-  out7 = vec_pack(out7l, out7h); \
-  out1 = vec_pack(out1l, out1h); \
-  \
-  tmp56l = vec_mergeh(tmp5, tmp6); \
-  tmp56h = vec_mergel(tmp5, tmp6); \
-  \
-  out5l = vec_msums(tmp56l, pw_mf050_mf256, z4l); \
-  out5h = vec_msums(tmp56h, pw_mf050_mf256, z4h); \
-  out3l = vec_msums(tmp56l, pw_mf256_f050, z3l); \
-  out3h = vec_msums(tmp56h, pw_mf256_f050, z3h); \
-  \
-  out5l = vec_sra(out5l, descale_p##PASS); \
-  out5h = vec_sra(out5h, descale_p##PASS); \
-  out3l = vec_sra(out3l, descale_p##PASS); \
-  out3h = vec_sra(out3h, descale_p##PASS); \
-  \
-  out5 = vec_pack(out5l, out5h); \
-  out3 = vec_pack(out3l, out3h); \
-}
-
-#define DO_FDCT_PASS1() { \
-  /* Even part */ \
-  \
-  tmp10 = vec_add(tmp0, tmp3); \
-  tmp13 = vec_sub(tmp0, tmp3); \
-  tmp11 = vec_add(tmp1, tmp2); \
-  tmp12 = vec_sub(tmp1, tmp2); \
-  \
-  out0  = vec_add(tmp10, tmp11); \
-  out0  = vec_sl(out0, pass1_bits); \
-  out4  = vec_sub(tmp10, tmp11); \
-  out4  = vec_sl(out4, pass1_bits); \
-  \
-  DO_FDCT_COMMON(1); \
-}
-
-#define DO_FDCT_PASS2() { \
-  /* Even part */ \
-  \
-  tmp10 = vec_add(tmp0, tmp3); \
-  tmp13 = vec_sub(tmp0, tmp3); \
-  tmp11 = vec_add(tmp1, tmp2); \
-  tmp12 = vec_sub(tmp1, tmp2); \
-  \
-  out0  = vec_add(tmp10, tmp11); \
-  out0  = vec_add(out0, pw_descale_p2x); \
-  out0  = vec_sra(out0, pass1_bits); \
-  out4  = vec_sub(tmp10, tmp11); \
-  out4  = vec_add(out4, pw_descale_p2x); \
-  out4  = vec_sra(out4, pass1_bits); \
-  \
-  DO_FDCT_COMMON(2); \
-}
-
-
-void jsimd_fdct_islow_altivec(DCTELEM *data)
-{
-  __vector short row0, row1, row2, row3, row4, row5, row6, row7,
-    col0, col1, col2, col3, col4, col5, col6, col7,
-    tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp10, tmp11, tmp12, tmp13,
-    tmp47l, tmp47h, tmp56l, tmp56h, tmp1312l, tmp1312h,
-    z3, z4, z34l, z34h,
-    out0, out1, out2, out3, out4, out5, out6, out7;
-  __vector int z3l, z3h, z4l, z4h,
-    out1l, out1h, out2l, out2h, out3l, out3h, out5l, out5h, out6l, out6h,
-    out7l, out7h;
-
-  /* Constants */
-  __vector short
-    pw_f130_f054 = { __4X2(F_0_541 + F_0_765, F_0_541) },
-    pw_f054_mf130 = { __4X2(F_0_541, F_0_541 - F_1_847) },
-    pw_mf078_f117 = { __4X2(F_1_175 - F_1_961, F_1_175) },
-    pw_f117_f078 = { __4X2(F_1_175, F_1_175 - F_0_390) },
-    pw_mf060_mf089 = { __4X2(F_0_298 - F_0_899, -F_0_899) },
-    pw_mf089_f060 = { __4X2(-F_0_899, F_1_501 - F_0_899) },
-    pw_mf050_mf256 = { __4X2(F_2_053 - F_2_562, -F_2_562) },
-    pw_mf256_f050 = { __4X2(-F_2_562, F_3_072 - F_2_562) },
-    pw_descale_p2x = { __8X(1 << (PASS1_BITS - 1)) };
-  __vector unsigned short pass1_bits = { __8X(PASS1_BITS) };
-  __vector int pd_descale_p1 = { __4X(1 << (DESCALE_P1 - 1)) },
-    pd_descale_p2 = { __4X(1 << (DESCALE_P2 - 1)) };
-  __vector unsigned int descale_p1 = { __4X(DESCALE_P1) },
-    descale_p2 = { __4X(DESCALE_P2) };
-
-  /* Pass 1: process rows */
-
-  row0 = vec_ld(0, data);
-  row1 = vec_ld(16, data);
-  row2 = vec_ld(32, data);
-  row3 = vec_ld(48, data);
-  row4 = vec_ld(64, data);
-  row5 = vec_ld(80, data);
-  row6 = vec_ld(96, data);
-  row7 = vec_ld(112, data);
-
-  TRANSPOSE(row, col);
-
-  tmp0 = vec_add(col0, col7);
-  tmp7 = vec_sub(col0, col7);
-  tmp1 = vec_add(col1, col6);
-  tmp6 = vec_sub(col1, col6);
-  tmp2 = vec_add(col2, col5);
-  tmp5 = vec_sub(col2, col5);
-  tmp3 = vec_add(col3, col4);
-  tmp4 = vec_sub(col3, col4);
-
-  DO_FDCT_PASS1();
-
-  /* Pass 2: process columns */
-
-  TRANSPOSE(out, row);
-
-  tmp0 = vec_add(row0, row7);
-  tmp7 = vec_sub(row0, row7);
-  tmp1 = vec_add(row1, row6);
-  tmp6 = vec_sub(row1, row6);
-  tmp2 = vec_add(row2, row5);
-  tmp5 = vec_sub(row2, row5);
-  tmp3 = vec_add(row3, row4);
-  tmp4 = vec_sub(row3, row4);
-
-  DO_FDCT_PASS2();
-
-  vec_st(out0, 0, data);
-  vec_st(out1, 16, data);
-  vec_st(out2, 32, data);
-  vec_st(out3, 48, data);
-  vec_st(out4, 64, data);
-  vec_st(out5, 80, data);
-  vec_st(out6, 96, data);
-  vec_st(out7, 112, data);
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jidctfst-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jidctfst-altivec.c
deleted file mode 100644
index 456c6c6..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jidctfst-altivec.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* FAST INTEGER INVERSE DCT
- *
- * This is similar to the SSE2 implementation, except that we left-shift the
- * constants by 1 less bit (the -1 in CONST_SHIFT.)  This is because
- * vec_madds(arg1, arg2, arg3) generates the 16-bit saturated sum of:
- *   the elements in arg3 + the most significant 17 bits of
- *     (the elements in arg1 * the elements in arg2).
- */
-
-#include "jsimd_altivec.h"
-
-
-#define F_1_082  277              /* FIX(1.082392200) */
-#define F_1_414  362              /* FIX(1.414213562) */
-#define F_1_847  473              /* FIX(1.847759065) */
-#define F_2_613  669              /* FIX(2.613125930) */
-#define F_1_613  (F_2_613 - 256)  /* FIX(2.613125930) - FIX(1) */
-
-#define CONST_BITS  8
-#define PASS1_BITS  2
-#define PRE_MULTIPLY_SCALE_BITS  2
-#define CONST_SHIFT  (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS - 1)
-
-
-#define DO_IDCT(in) { \
-  /* Even part */ \
-  \
-  tmp10 = vec_add(in##0, in##4); \
-  tmp11 = vec_sub(in##0, in##4); \
-  tmp13 = vec_add(in##2, in##6); \
-  \
-  tmp12 = vec_sub(in##2, in##6); \
-  tmp12 = vec_sl(tmp12, pre_multiply_scale_bits); \
-  tmp12 = vec_madds(tmp12, pw_F1414, pw_zero); \
-  tmp12 = vec_sub(tmp12, tmp13); \
-  \
-  tmp0 = vec_add(tmp10, tmp13); \
-  tmp3 = vec_sub(tmp10, tmp13); \
-  tmp1 = vec_add(tmp11, tmp12); \
-  tmp2 = vec_sub(tmp11, tmp12); \
-  \
-  /* Odd part */ \
-  \
-  z13 = vec_add(in##5, in##3); \
-  z10 = vec_sub(in##5, in##3); \
-  z10s = vec_sl(z10, pre_multiply_scale_bits); \
-  z11 = vec_add(in##1, in##7); \
-  z12s = vec_sub(in##1, in##7); \
-  z12s = vec_sl(z12s, pre_multiply_scale_bits); \
-  \
-  tmp11 = vec_sub(z11, z13); \
-  tmp11 = vec_sl(tmp11, pre_multiply_scale_bits); \
-  tmp11 = vec_madds(tmp11, pw_F1414, pw_zero); \
-  \
-  tmp7 = vec_add(z11, z13); \
-  \
-  /* To avoid overflow... \
-   * \
-   * (Original) \
-   * tmp12 = -2.613125930 * z10 + z5; \
-   * \
-   * (This implementation) \
-   * tmp12 = (-1.613125930 - 1) * z10 + z5; \
-   *       = -1.613125930 * z10 - z10 + z5; \
-   */ \
-  \
-  z5 = vec_add(z10s, z12s); \
-  z5 = vec_madds(z5, pw_F1847, pw_zero); \
-  \
-  tmp10 = vec_madds(z12s, pw_F1082, pw_zero); \
-  tmp10 = vec_sub(tmp10, z5); \
-  tmp12 = vec_madds(z10s, pw_MF1613, z5); \
-  tmp12 = vec_sub(tmp12, z10); \
-  \
-  tmp6 = vec_sub(tmp12, tmp7); \
-  tmp5 = vec_sub(tmp11, tmp6); \
-  tmp4 = vec_add(tmp10, tmp5); \
-  \
-  out0 = vec_add(tmp0, tmp7); \
-  out1 = vec_add(tmp1, tmp6); \
-  out2 = vec_add(tmp2, tmp5); \
-  out3 = vec_sub(tmp3, tmp4); \
-  out4 = vec_add(tmp3, tmp4); \
-  out5 = vec_sub(tmp2, tmp5); \
-  out6 = vec_sub(tmp1, tmp6); \
-  out7 = vec_sub(tmp0, tmp7); \
-}
-
-
-void jsimd_idct_ifast_altivec(void *dct_table_, JCOEFPTR coef_block,
-                              JSAMPARRAY output_buf, JDIMENSION output_col)
-{
-  short *dct_table = (short *)dct_table_;
-  int *outptr;
-
-  __vector short row0, row1, row2, row3, row4, row5, row6, row7,
-    col0, col1, col2, col3, col4, col5, col6, col7,
-    quant0, quant1, quant2, quant3, quant4, quant5, quant6, quant7,
-    tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp10, tmp11, tmp12, tmp13,
-    z5, z10, z10s, z11, z12s, z13,
-    out0, out1, out2, out3, out4, out5, out6, out7;
-  __vector signed char outb;
-
-  /* Constants */
-  __vector short pw_zero = { __8X(0) },
-    pw_F1414 = { __8X(F_1_414 << CONST_SHIFT) },
-    pw_F1847 = { __8X(F_1_847 << CONST_SHIFT) },
-    pw_MF1613 = { __8X(-F_1_613 << CONST_SHIFT) },
-    pw_F1082 = { __8X(F_1_082 << CONST_SHIFT) };
-  __vector unsigned short
-    pre_multiply_scale_bits = { __8X(PRE_MULTIPLY_SCALE_BITS) },
-    pass1_bits3 = { __8X(PASS1_BITS + 3) };
-  __vector signed char pb_centerjsamp = { __16X(CENTERJSAMPLE) };
-
-  /* Pass 1: process columns */
-
-  col0 = vec_ld(0, coef_block);
-  col1 = vec_ld(16, coef_block);
-  col2 = vec_ld(32, coef_block);
-  col3 = vec_ld(48, coef_block);
-  col4 = vec_ld(64, coef_block);
-  col5 = vec_ld(80, coef_block);
-  col6 = vec_ld(96, coef_block);
-  col7 = vec_ld(112, coef_block);
-
-  tmp1 = vec_or(col1, col2);
-  tmp2 = vec_or(col3, col4);
-  tmp1 = vec_or(tmp1, tmp2);
-  tmp3 = vec_or(col5, col6);
-  tmp3 = vec_or(tmp3, col7);
-  tmp1 = vec_or(tmp1, tmp3);
-
-  quant0 = vec_ld(0, dct_table);
-  col0 = vec_mladd(col0, quant0, pw_zero);
-
-  if (vec_all_eq(tmp1, pw_zero)) {
-    /* AC terms all zero */
-
-    row0 = vec_splat(col0, 0);
-    row1 = vec_splat(col0, 1);
-    row2 = vec_splat(col0, 2);
-    row3 = vec_splat(col0, 3);
-    row4 = vec_splat(col0, 4);
-    row5 = vec_splat(col0, 5);
-    row6 = vec_splat(col0, 6);
-    row7 = vec_splat(col0, 7);
-
-  } else {
-
-    quant1 = vec_ld(16, dct_table);
-    quant2 = vec_ld(32, dct_table);
-    quant3 = vec_ld(48, dct_table);
-    quant4 = vec_ld(64, dct_table);
-    quant5 = vec_ld(80, dct_table);
-    quant6 = vec_ld(96, dct_table);
-    quant7 = vec_ld(112, dct_table);
-
-    col1 = vec_mladd(col1, quant1, pw_zero);
-    col2 = vec_mladd(col2, quant2, pw_zero);
-    col3 = vec_mladd(col3, quant3, pw_zero);
-    col4 = vec_mladd(col4, quant4, pw_zero);
-    col5 = vec_mladd(col5, quant5, pw_zero);
-    col6 = vec_mladd(col6, quant6, pw_zero);
-    col7 = vec_mladd(col7, quant7, pw_zero);
-
-    DO_IDCT(col);
-
-    TRANSPOSE(out, row);
-  }
-
-  /* Pass 2: process rows */
-
-  DO_IDCT(row);
-
-  out0 = vec_sra(out0, pass1_bits3);
-  out1 = vec_sra(out1, pass1_bits3);
-  out2 = vec_sra(out2, pass1_bits3);
-  out3 = vec_sra(out3, pass1_bits3);
-  out4 = vec_sra(out4, pass1_bits3);
-  out5 = vec_sra(out5, pass1_bits3);
-  out6 = vec_sra(out6, pass1_bits3);
-  out7 = vec_sra(out7, pass1_bits3);
-
-  TRANSPOSE(out, col);
-
-  outb = vec_packs(col0, col0);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[0] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col1, col1);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[1] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col2, col2);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[2] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col3, col3);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[3] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col4, col4);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[4] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col5, col5);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[5] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col6, col6);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[6] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col7, col7);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[7] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jidctint-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jidctint-altivec.c
deleted file mode 100644
index 0e5dd58..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jidctint-altivec.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* SLOW INTEGER INVERSE DCT */
-
-#include "jsimd_altivec.h"
-
-
-#define F_0_298  2446   /* FIX(0.298631336) */
-#define F_0_390  3196   /* FIX(0.390180644) */
-#define F_0_541  4433   /* FIX(0.541196100) */
-#define F_0_765  6270   /* FIX(0.765366865) */
-#define F_0_899  7373   /* FIX(0.899976223) */
-#define F_1_175  9633   /* FIX(1.175875602) */
-#define F_1_501  12299  /* FIX(1.501321110) */
-#define F_1_847  15137  /* FIX(1.847759065) */
-#define F_1_961  16069  /* FIX(1.961570560) */
-#define F_2_053  16819  /* FIX(2.053119869) */
-#define F_2_562  20995  /* FIX(2.562915447) */
-#define F_3_072  25172  /* FIX(3.072711026) */
-
-#define CONST_BITS  13
-#define PASS1_BITS  2
-#define DESCALE_P1  (CONST_BITS - PASS1_BITS)
-#define DESCALE_P2  (CONST_BITS + PASS1_BITS + 3)
-
-
-#define DO_IDCT(in, PASS) { \
-  /* Even part \
-   * \
-   * (Original) \
-   * z1 = (z2 + z3) * 0.541196100; \
-   * tmp2 = z1 + z3 * -1.847759065; \
-   * tmp3 = z1 + z2 * 0.765366865; \
-   * \
-   * (This implementation) \
-   * tmp2 = z2 * 0.541196100 + z3 * (0.541196100 - 1.847759065); \
-   * tmp3 = z2 * (0.541196100 + 0.765366865) + z3 * 0.541196100; \
-   */ \
-  \
-  in##26l = vec_mergeh(in##2, in##6); \
-  in##26h = vec_mergel(in##2, in##6); \
-  \
-  tmp3l = vec_msums(in##26l, pw_f130_f054, pd_zero); \
-  tmp3h = vec_msums(in##26h, pw_f130_f054, pd_zero); \
-  tmp2l = vec_msums(in##26l, pw_f054_mf130, pd_zero); \
-  tmp2h = vec_msums(in##26h, pw_f054_mf130, pd_zero); \
-  \
-  tmp0 = vec_add(in##0, in##4); \
-  tmp1 = vec_sub(in##0, in##4); \
-  \
-  tmp0l = vec_unpackh(tmp0); \
-  tmp0h = vec_unpackl(tmp0); \
-  tmp0l = vec_sl(tmp0l, const_bits); \
-  tmp0h = vec_sl(tmp0h, const_bits); \
-  tmp0l = vec_add(tmp0l, pd_descale_p##PASS); \
-  tmp0h = vec_add(tmp0h, pd_descale_p##PASS); \
-  \
-  tmp10l = vec_add(tmp0l, tmp3l); \
-  tmp10h = vec_add(tmp0h, tmp3h); \
-  tmp13l = vec_sub(tmp0l, tmp3l); \
-  tmp13h = vec_sub(tmp0h, tmp3h); \
-  \
-  tmp1l = vec_unpackh(tmp1); \
-  tmp1h = vec_unpackl(tmp1); \
-  tmp1l = vec_sl(tmp1l, const_bits); \
-  tmp1h = vec_sl(tmp1h, const_bits); \
-  tmp1l = vec_add(tmp1l, pd_descale_p##PASS); \
-  tmp1h = vec_add(tmp1h, pd_descale_p##PASS); \
-  \
-  tmp11l = vec_add(tmp1l, tmp2l); \
-  tmp11h = vec_add(tmp1h, tmp2h); \
-  tmp12l = vec_sub(tmp1l, tmp2l); \
-  tmp12h = vec_sub(tmp1h, tmp2h); \
-  \
-  /* Odd part */ \
-  \
-  z3 = vec_add(in##3, in##7); \
-  z4 = vec_add(in##1, in##5); \
-  \
-  /* (Original) \
-   * z5 = (z3 + z4) * 1.175875602; \
-   * z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644; \
-   * z3 += z5;  z4 += z5; \
-   * \
-   * (This implementation) \
-   * z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602; \
-   * z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644); \
-   */ \
-  \
-  z34l = vec_mergeh(z3, z4); \
-  z34h = vec_mergel(z3, z4); \
-  \
-  z3l = vec_msums(z34l, pw_mf078_f117, pd_zero); \
-  z3h = vec_msums(z34h, pw_mf078_f117, pd_zero); \
-  z4l = vec_msums(z34l, pw_f117_f078, pd_zero); \
-  z4h = vec_msums(z34h, pw_f117_f078, pd_zero); \
-  \
-  /* (Original) \
-   * z1 = tmp0 + tmp3;  z2 = tmp1 + tmp2; \
-   * tmp0 = tmp0 * 0.298631336;  tmp1 = tmp1 * 2.053119869; \
-   * tmp2 = tmp2 * 3.072711026;  tmp3 = tmp3 * 1.501321110; \
-   * z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447; \
-   * tmp0 += z1 + z3;  tmp1 += z2 + z4; \
-   * tmp2 += z2 + z3;  tmp3 += z1 + z4; \
-   * \
-   * (This implementation) \
-   * tmp0 = tmp0 * (0.298631336 - 0.899976223) + tmp3 * -0.899976223; \
-   * tmp1 = tmp1 * (2.053119869 - 2.562915447) + tmp2 * -2.562915447; \
-   * tmp2 = tmp1 * -2.562915447 + tmp2 * (3.072711026 - 2.562915447); \
-   * tmp3 = tmp0 * -0.899976223 + tmp3 * (1.501321110 - 0.899976223); \
-   * tmp0 += z3;  tmp1 += z4; \
-   * tmp2 += z3;  tmp3 += z4; \
-   */ \
-  \
-  in##71l = vec_mergeh(in##7, in##1); \
-  in##71h = vec_mergel(in##7, in##1); \
-  \
-  tmp0l = vec_msums(in##71l, pw_mf060_mf089, z3l); \
-  tmp0h = vec_msums(in##71h, pw_mf060_mf089, z3h); \
-  tmp3l = vec_msums(in##71l, pw_mf089_f060, z4l); \
-  tmp3h = vec_msums(in##71h, pw_mf089_f060, z4h); \
-  \
-  in##53l = vec_mergeh(in##5, in##3); \
-  in##53h = vec_mergel(in##5, in##3); \
-  \
-  tmp1l = vec_msums(in##53l, pw_mf050_mf256, z4l); \
-  tmp1h = vec_msums(in##53h, pw_mf050_mf256, z4h); \
-  tmp2l = vec_msums(in##53l, pw_mf256_f050, z3l); \
-  tmp2h = vec_msums(in##53h, pw_mf256_f050, z3h); \
-  \
-  /* Final output stage */ \
-  \
-  out0l = vec_add(tmp10l, tmp3l); \
-  out0h = vec_add(tmp10h, tmp3h); \
-  out7l = vec_sub(tmp10l, tmp3l); \
-  out7h = vec_sub(tmp10h, tmp3h); \
-  \
-  out0l = vec_sra(out0l, descale_p##PASS); \
-  out0h = vec_sra(out0h, descale_p##PASS); \
-  out7l = vec_sra(out7l, descale_p##PASS); \
-  out7h = vec_sra(out7h, descale_p##PASS); \
-  \
-  out0 = vec_pack(out0l, out0h); \
-  out7 = vec_pack(out7l, out7h); \
-  \
-  out1l = vec_add(tmp11l, tmp2l); \
-  out1h = vec_add(tmp11h, tmp2h); \
-  out6l = vec_sub(tmp11l, tmp2l); \
-  out6h = vec_sub(tmp11h, tmp2h); \
-  \
-  out1l = vec_sra(out1l, descale_p##PASS); \
-  out1h = vec_sra(out1h, descale_p##PASS); \
-  out6l = vec_sra(out6l, descale_p##PASS); \
-  out6h = vec_sra(out6h, descale_p##PASS); \
-  \
-  out1 = vec_pack(out1l, out1h); \
-  out6 = vec_pack(out6l, out6h); \
-  \
-  out2l = vec_add(tmp12l, tmp1l); \
-  out2h = vec_add(tmp12h, tmp1h); \
-  out5l = vec_sub(tmp12l, tmp1l); \
-  out5h = vec_sub(tmp12h, tmp1h); \
-  \
-  out2l = vec_sra(out2l, descale_p##PASS); \
-  out2h = vec_sra(out2h, descale_p##PASS); \
-  out5l = vec_sra(out5l, descale_p##PASS); \
-  out5h = vec_sra(out5h, descale_p##PASS); \
-  \
-  out2 = vec_pack(out2l, out2h); \
-  out5 = vec_pack(out5l, out5h); \
-  \
-  out3l = vec_add(tmp13l, tmp0l); \
-  out3h = vec_add(tmp13h, tmp0h); \
-  out4l = vec_sub(tmp13l, tmp0l); \
-  out4h = vec_sub(tmp13h, tmp0h); \
-  \
-  out3l = vec_sra(out3l, descale_p##PASS); \
-  out3h = vec_sra(out3h, descale_p##PASS); \
-  out4l = vec_sra(out4l, descale_p##PASS); \
-  out4h = vec_sra(out4h, descale_p##PASS); \
-  \
-  out3 = vec_pack(out3l, out3h); \
-  out4 = vec_pack(out4l, out4h); \
-}
-
-
-void jsimd_idct_islow_altivec(void *dct_table_, JCOEFPTR coef_block,
-                              JSAMPARRAY output_buf, JDIMENSION output_col)
-{
-  short *dct_table = (short *)dct_table_;
-  int *outptr;
-
-  __vector short row0, row1, row2, row3, row4, row5, row6, row7,
-    col0, col1, col2, col3, col4, col5, col6, col7,
-    quant0, quant1, quant2, quant3, quant4, quant5, quant6, quant7,
-    tmp0, tmp1, tmp2, tmp3, z3, z4,
-    z34l, z34h, col71l, col71h, col26l, col26h, col53l, col53h,
-    row71l, row71h, row26l, row26h, row53l, row53h,
-    out0, out1, out2, out3, out4, out5, out6, out7;
-  __vector int tmp0l, tmp0h, tmp1l, tmp1h, tmp2l, tmp2h, tmp3l, tmp3h,
-    tmp10l, tmp10h, tmp11l, tmp11h, tmp12l, tmp12h, tmp13l, tmp13h,
-    z3l, z3h, z4l, z4h,
-    out0l, out0h, out1l, out1h, out2l, out2h, out3l, out3h, out4l, out4h,
-    out5l, out5h, out6l, out6h, out7l, out7h;
-  __vector signed char outb;
-
-  /* Constants */
-  __vector short pw_zero = { __8X(0) },
-    pw_f130_f054 = { __4X2(F_0_541 + F_0_765, F_0_541) },
-    pw_f054_mf130 = { __4X2(F_0_541, F_0_541 - F_1_847) },
-    pw_mf078_f117 = { __4X2(F_1_175 - F_1_961, F_1_175) },
-    pw_f117_f078 = { __4X2(F_1_175, F_1_175 - F_0_390) },
-    pw_mf060_mf089 = { __4X2(F_0_298 - F_0_899, -F_0_899) },
-    pw_mf089_f060 = { __4X2(-F_0_899, F_1_501 - F_0_899) },
-    pw_mf050_mf256 = { __4X2(F_2_053 - F_2_562, -F_2_562) },
-    pw_mf256_f050 = { __4X2(-F_2_562, F_3_072 - F_2_562) };
-  __vector unsigned short pass1_bits = { __8X(PASS1_BITS) };
-  __vector int pd_zero = { __4X(0) },
-    pd_descale_p1 = { __4X(1 << (DESCALE_P1 - 1)) },
-    pd_descale_p2 = { __4X(1 << (DESCALE_P2 - 1)) };
-  __vector unsigned int descale_p1 = { __4X(DESCALE_P1) },
-    descale_p2 = { __4X(DESCALE_P2) },
-    const_bits = { __4X(CONST_BITS) };
-  __vector signed char pb_centerjsamp = { __16X(CENTERJSAMPLE) };
-
-  /* Pass 1: process columns */
-
-  col0 = vec_ld(0, coef_block);
-  col1 = vec_ld(16, coef_block);
-  col2 = vec_ld(32, coef_block);
-  col3 = vec_ld(48, coef_block);
-  col4 = vec_ld(64, coef_block);
-  col5 = vec_ld(80, coef_block);
-  col6 = vec_ld(96, coef_block);
-  col7 = vec_ld(112, coef_block);
-
-  tmp1 = vec_or(col1, col2);
-  tmp2 = vec_or(col3, col4);
-  tmp1 = vec_or(tmp1, tmp2);
-  tmp3 = vec_or(col5, col6);
-  tmp3 = vec_or(tmp3, col7);
-  tmp1 = vec_or(tmp1, tmp3);
-
-  quant0 = vec_ld(0, dct_table);
-  col0 = vec_mladd(col0, quant0, pw_zero);
-
-  if (vec_all_eq(tmp1, pw_zero)) {
-    /* AC terms all zero */
-
-    col0 = vec_sl(col0, pass1_bits);
-
-    row0 = vec_splat(col0, 0);
-    row1 = vec_splat(col0, 1);
-    row2 = vec_splat(col0, 2);
-    row3 = vec_splat(col0, 3);
-    row4 = vec_splat(col0, 4);
-    row5 = vec_splat(col0, 5);
-    row6 = vec_splat(col0, 6);
-    row7 = vec_splat(col0, 7);
-
-  } else {
-
-    quant1 = vec_ld(16, dct_table);
-    quant2 = vec_ld(32, dct_table);
-    quant3 = vec_ld(48, dct_table);
-    quant4 = vec_ld(64, dct_table);
-    quant5 = vec_ld(80, dct_table);
-    quant6 = vec_ld(96, dct_table);
-    quant7 = vec_ld(112, dct_table);
-
-    col1 = vec_mladd(col1, quant1, pw_zero);
-    col2 = vec_mladd(col2, quant2, pw_zero);
-    col3 = vec_mladd(col3, quant3, pw_zero);
-    col4 = vec_mladd(col4, quant4, pw_zero);
-    col5 = vec_mladd(col5, quant5, pw_zero);
-    col6 = vec_mladd(col6, quant6, pw_zero);
-    col7 = vec_mladd(col7, quant7, pw_zero);
-
-    DO_IDCT(col, 1);
-
-    TRANSPOSE(out, row);
-  }
-
-  /* Pass 2: process rows */
-
-  DO_IDCT(row, 2);
-
-  TRANSPOSE(out, col);
-
-  outb = vec_packs(col0, col0);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[0] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col1, col1);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[1] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col2, col2);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[2] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col3, col3);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[3] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col4, col4);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[4] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col5, col5);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[5] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col6, col6);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[6] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-
-  outb = vec_packs(col7, col7);
-  outb = vec_add(outb, pb_centerjsamp);
-  outptr = (int *)(output_buf[7] + output_col);
-  vec_ste((__vector int)outb, 0, outptr);
-  vec_ste((__vector int)outb, 4, outptr);
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jquanti-altivec.c b/src/third_party/libjpeg-turbo/simd/powerpc/jquanti-altivec.c
deleted file mode 100644
index 7d6e325..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jquanti-altivec.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-/* INTEGER QUANTIZATION AND SAMPLE CONVERSION */
-
-#include "jsimd_altivec.h"
-
-
-/* NOTE: The address will either be aligned or offset by 8 bytes, so we can
- * always get the data we want by using a single vector load (although we may
- * have to permute the result.)
- */
-#if __BIG_ENDIAN__
-
-#define LOAD_ROW(row) { \
-  elemptr = sample_data[row] + start_col; \
-  in##row = vec_ld(0, elemptr); \
-  if ((size_t)elemptr & 15) \
-    in##row = vec_perm(in##row, in##row, vec_lvsl(0, elemptr)); \
-}
-
-#else
-
-#define LOAD_ROW(row) { \
-  elemptr = sample_data[row] + start_col; \
-  in##row = vec_vsx_ld(0, elemptr); \
-}
-
-#endif
-
-
-void jsimd_convsamp_altivec(JSAMPARRAY sample_data, JDIMENSION start_col,
-                            DCTELEM *workspace)
-{
-  JSAMPROW elemptr;
-
-  __vector unsigned char in0, in1, in2, in3, in4, in5, in6, in7;
-  __vector short out0, out1, out2, out3, out4, out5, out6, out7;
-
-  /* Constants */
-  __vector short pw_centerjsamp = { __8X(CENTERJSAMPLE) };
-  __vector unsigned char pb_zero = { __16X(0) };
-
-  LOAD_ROW(0);
-  LOAD_ROW(1);
-  LOAD_ROW(2);
-  LOAD_ROW(3);
-  LOAD_ROW(4);
-  LOAD_ROW(5);
-  LOAD_ROW(6);
-  LOAD_ROW(7);
-
-  out0 = (__vector short)VEC_UNPACKHU(in0);
-  out1 = (__vector short)VEC_UNPACKHU(in1);
-  out2 = (__vector short)VEC_UNPACKHU(in2);
-  out3 = (__vector short)VEC_UNPACKHU(in3);
-  out4 = (__vector short)VEC_UNPACKHU(in4);
-  out5 = (__vector short)VEC_UNPACKHU(in5);
-  out6 = (__vector short)VEC_UNPACKHU(in6);
-  out7 = (__vector short)VEC_UNPACKHU(in7);
-
-  out0 = vec_sub(out0, pw_centerjsamp);
-  out1 = vec_sub(out1, pw_centerjsamp);
-  out2 = vec_sub(out2, pw_centerjsamp);
-  out3 = vec_sub(out3, pw_centerjsamp);
-  out4 = vec_sub(out4, pw_centerjsamp);
-  out5 = vec_sub(out5, pw_centerjsamp);
-  out6 = vec_sub(out6, pw_centerjsamp);
-  out7 = vec_sub(out7, pw_centerjsamp);
-
-  vec_st(out0, 0, workspace);
-  vec_st(out1, 16, workspace);
-  vec_st(out2, 32, workspace);
-  vec_st(out3, 48, workspace);
-  vec_st(out4, 64, workspace);
-  vec_st(out5, 80, workspace);
-  vec_st(out6, 96, workspace);
-  vec_st(out7, 112, workspace);
-}
-
-
-#define WORD_BIT  16
-
-/* There is no AltiVec 16-bit unsigned multiply instruction, hence this.
-   We basically need an unsigned equivalent of vec_madds(). */
-
-#define MULTIPLY(vs0, vs1, out) { \
-  tmpe = vec_mule((__vector unsigned short)vs0, \
-                  (__vector unsigned short)vs1); \
-  tmpo = vec_mulo((__vector unsigned short)vs0, \
-                  (__vector unsigned short)vs1); \
-  out = (__vector short)vec_perm((__vector unsigned short)tmpe, \
-                                 (__vector unsigned short)tmpo, \
-                                 shift_pack_index); \
-}
-
-void jsimd_quantize_altivec(JCOEFPTR coef_block, DCTELEM *divisors,
-                            DCTELEM *workspace)
-{
-  __vector short row0, row1, row2, row3, row4, row5, row6, row7,
-    row0s, row1s, row2s, row3s, row4s, row5s, row6s, row7s,
-    corr0, corr1, corr2, corr3, corr4, corr5, corr6, corr7,
-    recip0, recip1, recip2, recip3, recip4, recip5, recip6, recip7,
-    scale0, scale1, scale2, scale3, scale4, scale5, scale6, scale7;
-  __vector unsigned int tmpe, tmpo;
-
-  /* Constants */
-  __vector unsigned short pw_word_bit_m1 = { __8X(WORD_BIT - 1) };
-#if __BIG_ENDIAN__
-  __vector unsigned char shift_pack_index =
-    {  0,  1, 16, 17,  4,  5, 20, 21,  8,  9, 24, 25, 12, 13, 28, 29 };
-#else
-  __vector unsigned char shift_pack_index =
-    {  2,  3, 18, 19,  6,  7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31 };
-#endif
-
-  row0 = vec_ld(0, workspace);
-  row1 = vec_ld(16, workspace);
-  row2 = vec_ld(32, workspace);
-  row3 = vec_ld(48, workspace);
-  row4 = vec_ld(64, workspace);
-  row5 = vec_ld(80, workspace);
-  row6 = vec_ld(96, workspace);
-  row7 = vec_ld(112, workspace);
-
-  /* Branch-less absolute value */
-  row0s = vec_sra(row0, pw_word_bit_m1);
-  row1s = vec_sra(row1, pw_word_bit_m1);
-  row2s = vec_sra(row2, pw_word_bit_m1);
-  row3s = vec_sra(row3, pw_word_bit_m1);
-  row4s = vec_sra(row4, pw_word_bit_m1);
-  row5s = vec_sra(row5, pw_word_bit_m1);
-  row6s = vec_sra(row6, pw_word_bit_m1);
-  row7s = vec_sra(row7, pw_word_bit_m1);
-  row0 = vec_xor(row0, row0s);
-  row1 = vec_xor(row1, row1s);
-  row2 = vec_xor(row2, row2s);
-  row3 = vec_xor(row3, row3s);
-  row4 = vec_xor(row4, row4s);
-  row5 = vec_xor(row5, row5s);
-  row6 = vec_xor(row6, row6s);
-  row7 = vec_xor(row7, row7s);
-  row0 = vec_sub(row0, row0s);
-  row1 = vec_sub(row1, row1s);
-  row2 = vec_sub(row2, row2s);
-  row3 = vec_sub(row3, row3s);
-  row4 = vec_sub(row4, row4s);
-  row5 = vec_sub(row5, row5s);
-  row6 = vec_sub(row6, row6s);
-  row7 = vec_sub(row7, row7s);
-
-  corr0 = vec_ld(DCTSIZE2 * 2, divisors);
-  corr1 = vec_ld(DCTSIZE2 * 2 + 16, divisors);
-  corr2 = vec_ld(DCTSIZE2 * 2 + 32, divisors);
-  corr3 = vec_ld(DCTSIZE2 * 2 + 48, divisors);
-  corr4 = vec_ld(DCTSIZE2 * 2 + 64, divisors);
-  corr5 = vec_ld(DCTSIZE2 * 2 + 80, divisors);
-  corr6 = vec_ld(DCTSIZE2 * 2 + 96, divisors);
-  corr7 = vec_ld(DCTSIZE2 * 2 + 112, divisors);
-
-  row0 = vec_add(row0, corr0);
-  row1 = vec_add(row1, corr1);
-  row2 = vec_add(row2, corr2);
-  row3 = vec_add(row3, corr3);
-  row4 = vec_add(row4, corr4);
-  row5 = vec_add(row5, corr5);
-  row6 = vec_add(row6, corr6);
-  row7 = vec_add(row7, corr7);
-
-  recip0 = vec_ld(0, divisors);
-  recip1 = vec_ld(16, divisors);
-  recip2 = vec_ld(32, divisors);
-  recip3 = vec_ld(48, divisors);
-  recip4 = vec_ld(64, divisors);
-  recip5 = vec_ld(80, divisors);
-  recip6 = vec_ld(96, divisors);
-  recip7 = vec_ld(112, divisors);
-
-  MULTIPLY(row0, recip0, row0);
-  MULTIPLY(row1, recip1, row1);
-  MULTIPLY(row2, recip2, row2);
-  MULTIPLY(row3, recip3, row3);
-  MULTIPLY(row4, recip4, row4);
-  MULTIPLY(row5, recip5, row5);
-  MULTIPLY(row6, recip6, row6);
-  MULTIPLY(row7, recip7, row7);
-
-  scale0 = vec_ld(DCTSIZE2 * 4, divisors);
-  scale1 = vec_ld(DCTSIZE2 * 4 + 16, divisors);
-  scale2 = vec_ld(DCTSIZE2 * 4 + 32, divisors);
-  scale3 = vec_ld(DCTSIZE2 * 4 + 48, divisors);
-  scale4 = vec_ld(DCTSIZE2 * 4 + 64, divisors);
-  scale5 = vec_ld(DCTSIZE2 * 4 + 80, divisors);
-  scale6 = vec_ld(DCTSIZE2 * 4 + 96, divisors);
-  scale7 = vec_ld(DCTSIZE2 * 4 + 112, divisors);
-
-  MULTIPLY(row0, scale0, row0);
-  MULTIPLY(row1, scale1, row1);
-  MULTIPLY(row2, scale2, row2);
-  MULTIPLY(row3, scale3, row3);
-  MULTIPLY(row4, scale4, row4);
-  MULTIPLY(row5, scale5, row5);
-  MULTIPLY(row6, scale6, row6);
-  MULTIPLY(row7, scale7, row7);
-
-  row0 = vec_xor(row0, row0s);
-  row1 = vec_xor(row1, row1s);
-  row2 = vec_xor(row2, row2s);
-  row3 = vec_xor(row3, row3s);
-  row4 = vec_xor(row4, row4s);
-  row5 = vec_xor(row5, row5s);
-  row6 = vec_xor(row6, row6s);
-  row7 = vec_xor(row7, row7s);
-  row0 = vec_sub(row0, row0s);
-  row1 = vec_sub(row1, row1s);
-  row2 = vec_sub(row2, row2s);
-  row3 = vec_sub(row3, row3s);
-  row4 = vec_sub(row4, row4s);
-  row5 = vec_sub(row5, row5s);
-  row6 = vec_sub(row6, row6s);
-  row7 = vec_sub(row7, row7s);
-
-  vec_st(row0, 0, coef_block);
-  vec_st(row1, 16, coef_block);
-  vec_st(row2, 32, coef_block);
-  vec_st(row3, 48, coef_block);
-  vec_st(row4, 64, coef_block);
-  vec_st(row5, 80, coef_block);
-  vec_st(row6, 96, coef_block);
-  vec_st(row7, 112, coef_block);
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jsimd.c b/src/third_party/libjpeg-turbo/simd/powerpc/jsimd.c
deleted file mode 100644
index d0d3981..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jsimd.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * jsimd_powerpc.c
- *
- * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2009-2011, 2014-2016, 2018, D. R. Commander.
- * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
- *
- * Based on the x86 SIMD extension for IJG JPEG library,
- * Copyright (C) 1999-2006, MIYASAKA Masaru.
- * For conditions of distribution and use, see copyright notice in jsimdext.inc
- *
- * This file contains the interface between the "normal" portions
- * of the library and the SIMD implementations when running on a
- * PowerPC architecture.
- */
-
-#ifdef __amigaos4__
-/* This must be defined first as it re-defines GLOBAL otherwise */
-#include <proto/exec.h>
-#endif
-
-#define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
-#include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#if defined(__OpenBSD__)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <machine/cpu.h>
-#endif
-
-static unsigned int simd_support = ~0;
-
-#if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
-
-#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
-
-LOCAL(int)
-check_feature(char *buffer, char *feature)
-{
-  char *p;
-
-  if (*feature == 0)
-    return 0;
-  if (strncmp(buffer, "cpu", 3) != 0)
-    return 0;
-  buffer += 3;
-  while (isspace(*buffer))
-    buffer++;
-
-  /* Check if 'feature' is present in the buffer as a separate word */
-  while ((p = strstr(buffer, feature))) {
-    if (p > buffer && !isspace(*(p - 1))) {
-      buffer++;
-      continue;
-    }
-    p += strlen(feature);
-    if (*p != 0 && !isspace(*p)) {
-      buffer++;
-      continue;
-    }
-    return 1;
-  }
-  return 0;
-}
-
-LOCAL(int)
-parse_proc_cpuinfo(int bufsize)
-{
-  char *buffer = (char *)malloc(bufsize);
-  FILE *fd;
-
-  simd_support = 0;
-
-  if (!buffer)
-    return 0;
-
-  fd = fopen("/proc/cpuinfo", "r");
-  if (fd) {
-    while (fgets(buffer, bufsize, fd)) {
-      if (!strchr(buffer, '\n') && !feof(fd)) {
-        /* "impossible" happened - insufficient size of the buffer! */
-        fclose(fd);
-        free(buffer);
-        return 0;
-      }
-      if (check_feature(buffer, "altivec"))
-        simd_support |= JSIMD_ALTIVEC;
-    }
-    fclose(fd);
-  }
-  free(buffer);
-  return 1;
-}
-
-#endif
-
-/*
- * Check what SIMD accelerations are supported.
- *
- * FIXME: This code is racy under a multi-threaded environment.
- */
-LOCAL(void)
-init_simd(void)
-{
-#ifndef NO_GETENV
-  char *env = NULL;
-#endif
-#if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
-  int bufsize = 1024; /* an initial guess for the line buffer size limit */
-#elif defined(__amigaos4__)
-  uint32 altivec = 0;
-#elif defined(__OpenBSD__)
-  int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
-  int altivec;
-  size_t len = sizeof(altivec);
-#endif
-
-  if (simd_support != ~0U)
-    return;
-
-  simd_support = 0;
-
-#if defined(__ALTIVEC__) || defined(__APPLE__)
-  simd_support |= JSIMD_ALTIVEC;
-#elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
-  while (!parse_proc_cpuinfo(bufsize)) {
-    bufsize *= 2;
-    if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
-      break;
-  }
-#elif defined(__amigaos4__)
-  IExec->GetCPUInfoTags(GCIT_VectorUnit, &altivec, TAG_DONE);
-  if (altivec == VECTORTYPE_ALTIVEC)
-    simd_support |= JSIMD_ALTIVEC;
-#elif defined(__OpenBSD__)
-  if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0)
-    simd_support |= JSIMD_ALTIVEC;
-#endif
-
-#ifndef NO_GETENV
-  /* Force different settings through environment variables */
-  env = getenv("JSIMD_FORCEALTIVEC");
-  if ((env != NULL) && (strcmp(env, "1") == 0))
-    simd_support = JSIMD_ALTIVEC;
-  env = getenv("JSIMD_FORCENONE");
-  if ((env != NULL) && (strcmp(env, "1") == 0))
-    simd_support = 0;
-#endif
-}
-
-GLOBAL(int)
-jsimd_can_rgb_ycc(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_rgb_gray(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_ycc_rgb565(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                      JSAMPIMAGE output_buf, JDIMENSION output_row,
-                      int num_rows)
-{
-  void (*altivecfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
-
-  switch (cinfo->in_color_space) {
-  case JCS_EXT_RGB:
-    altivecfct = jsimd_extrgb_ycc_convert_altivec;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    altivecfct = jsimd_extrgbx_ycc_convert_altivec;
-    break;
-  case JCS_EXT_BGR:
-    altivecfct = jsimd_extbgr_ycc_convert_altivec;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    altivecfct = jsimd_extbgrx_ycc_convert_altivec;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    altivecfct = jsimd_extxbgr_ycc_convert_altivec;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    altivecfct = jsimd_extxrgb_ycc_convert_altivec;
-    break;
-  default:
-    altivecfct = jsimd_rgb_ycc_convert_altivec;
-    break;
-  }
-
-  altivecfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
-}
-
-GLOBAL(void)
-jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
-                       JSAMPIMAGE output_buf, JDIMENSION output_row,
-                       int num_rows)
-{
-  void (*altivecfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
-
-  switch (cinfo->in_color_space) {
-  case JCS_EXT_RGB:
-    altivecfct = jsimd_extrgb_gray_convert_altivec;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    altivecfct = jsimd_extrgbx_gray_convert_altivec;
-    break;
-  case JCS_EXT_BGR:
-    altivecfct = jsimd_extbgr_gray_convert_altivec;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    altivecfct = jsimd_extbgrx_gray_convert_altivec;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    altivecfct = jsimd_extxbgr_gray_convert_altivec;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    altivecfct = jsimd_extxrgb_gray_convert_altivec;
-    break;
-  default:
-    altivecfct = jsimd_rgb_gray_convert_altivec;
-    break;
-  }
-
-  altivecfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                      JDIMENSION input_row, JSAMPARRAY output_buf,
-                      int num_rows)
-{
-  void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    altivecfct = jsimd_ycc_extrgb_convert_altivec;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    altivecfct = jsimd_ycc_extrgbx_convert_altivec;
-    break;
-  case JCS_EXT_BGR:
-    altivecfct = jsimd_ycc_extbgr_convert_altivec;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    altivecfct = jsimd_ycc_extbgrx_convert_altivec;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    altivecfct = jsimd_ycc_extxbgr_convert_altivec;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    altivecfct = jsimd_ycc_extxrgb_convert_altivec;
-    break;
-  default:
-    altivecfct = jsimd_ycc_rgb_convert_altivec;
-    break;
-  }
-
-  altivecfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
-}
-
-GLOBAL(void)
-jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                         JDIMENSION input_row, JSAMPARRAY output_buf,
-                         int num_rows)
-{
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_downsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v2_downsample_altivec(cinfo->image_width, cinfo->max_v_samp_factor,
-                                compptr->v_samp_factor,
-                                compptr->width_in_blocks, input_data,
-                                output_data);
-}
-
-GLOBAL(void)
-jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
-                      JSAMPARRAY input_data, JSAMPARRAY output_data)
-{
-  jsimd_h2v1_downsample_altivec(cinfo->image_width, cinfo->max_v_samp_factor,
-                                compptr->v_samp_factor,
-                                compptr->width_in_blocks, input_data,
-                                output_data);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v2_upsample_altivec(cinfo->max_v_samp_factor, cinfo->output_width,
-                              input_data, output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v1_upsample_altivec(cinfo->max_v_samp_factor, cinfo->output_width,
-                              input_data, output_data_ptr);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_fancy_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_fancy_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v2_fancy_upsample_altivec(cinfo->max_v_samp_factor,
-                                    compptr->downsampled_width, input_data,
-                                    output_data_ptr);
-}
-
-GLOBAL(void)
-jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
-{
-  jsimd_h2v1_fancy_upsample_altivec(cinfo->max_v_samp_factor,
-                                    compptr->downsampled_width, input_data,
-                                    output_data_ptr);
-}
-
-GLOBAL(int)
-jsimd_can_h2v2_merged_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_h2v1_merged_upsample(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-  void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    altivecfct = jsimd_h2v2_extrgb_merged_upsample_altivec;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    altivecfct = jsimd_h2v2_extrgbx_merged_upsample_altivec;
-    break;
-  case JCS_EXT_BGR:
-    altivecfct = jsimd_h2v2_extbgr_merged_upsample_altivec;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    altivecfct = jsimd_h2v2_extbgrx_merged_upsample_altivec;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    altivecfct = jsimd_h2v2_extxbgr_merged_upsample_altivec;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    altivecfct = jsimd_h2v2_extxrgb_merged_upsample_altivec;
-    break;
-  default:
-    altivecfct = jsimd_h2v2_merged_upsample_altivec;
-    break;
-  }
-
-  altivecfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
-}
-
-GLOBAL(void)
-jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
-                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
-{
-  void (*altivecfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
-
-  switch (cinfo->out_color_space) {
-  case JCS_EXT_RGB:
-    altivecfct = jsimd_h2v1_extrgb_merged_upsample_altivec;
-    break;
-  case JCS_EXT_RGBX:
-  case JCS_EXT_RGBA:
-    altivecfct = jsimd_h2v1_extrgbx_merged_upsample_altivec;
-    break;
-  case JCS_EXT_BGR:
-    altivecfct = jsimd_h2v1_extbgr_merged_upsample_altivec;
-    break;
-  case JCS_EXT_BGRX:
-  case JCS_EXT_BGRA:
-    altivecfct = jsimd_h2v1_extbgrx_merged_upsample_altivec;
-    break;
-  case JCS_EXT_XBGR:
-  case JCS_EXT_ABGR:
-    altivecfct = jsimd_h2v1_extxbgr_merged_upsample_altivec;
-    break;
-  case JCS_EXT_XRGB:
-  case JCS_EXT_ARGB:
-    altivecfct = jsimd_h2v1_extxrgb_merged_upsample_altivec;
-    break;
-  default:
-    altivecfct = jsimd_h2v1_merged_upsample_altivec;
-    break;
-  }
-
-  altivecfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
-}
-
-GLOBAL(int)
-jsimd_can_convsamp(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (BITS_IN_JSAMPLE != 8)
-    return 0;
-  if (sizeof(JDIMENSION) != 4)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_convsamp_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
-               DCTELEM *workspace)
-{
-  jsimd_convsamp_altivec(sample_data, start_col, workspace);
-}
-
-GLOBAL(void)
-jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
-                     FAST_FLOAT *workspace)
-{
-}
-
-GLOBAL(int)
-jsimd_can_fdct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_ifast(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_fdct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_fdct_islow(DCTELEM *data)
-{
-  jsimd_fdct_islow_altivec(data);
-}
-
-GLOBAL(void)
-jsimd_fdct_ifast(DCTELEM *data)
-{
-  jsimd_fdct_ifast_altivec(data);
-}
-
-GLOBAL(void)
-jsimd_fdct_float(FAST_FLOAT *data)
-{
-}
-
-GLOBAL(int)
-jsimd_can_quantize(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-  if (sizeof(DCTELEM) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_quantize_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
-{
-  jsimd_quantize_altivec(coef_block, divisors, workspace);
-}
-
-GLOBAL(void)
-jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
-                     FAST_FLOAT *workspace)
-{
-}
-
-GLOBAL(int)
-jsimd_can_idct_2x2(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_4x4(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-}
-
-GLOBAL(void)
-jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-               JCOEFPTR coef_block, JSAMPARRAY output_buf,
-               JDIMENSION output_col)
-{
-}
-
-GLOBAL(int)
-jsimd_can_idct_islow(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_ifast(void)
-{
-  init_simd();
-
-  /* The code is optimised for these values only */
-  if (DCTSIZE != 8)
-    return 0;
-  if (sizeof(JCOEF) != 2)
-    return 0;
-
-  if (simd_support & JSIMD_ALTIVEC)
-    return 1;
-
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_can_idct_float(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  jsimd_idct_islow_altivec(compptr->dct_table, coef_block, output_buf,
-                           output_col);
-}
-
-GLOBAL(void)
-jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-  jsimd_idct_ifast_altivec(compptr->dct_table, coef_block, output_buf,
-                           output_col);
-}
-
-GLOBAL(void)
-jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
-                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
-                 JDIMENSION output_col)
-{
-}
-
-GLOBAL(int)
-jsimd_can_huff_encode_one_block(void)
-{
-  return 0;
-}
-
-GLOBAL(JOCTET *)
-jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
-                            int last_dc_val, c_derived_tbl *dctbl,
-                            c_derived_tbl *actbl)
-{
-  return NULL;
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_first_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(void)
-jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
-                                  const int *jpeg_natural_order_start, int Sl,
-                                  int Al, JCOEF *values, size_t *zerobits)
-{
-}
-
-GLOBAL(int)
-jsimd_can_encode_mcu_AC_refine_prepare(void)
-{
-  return 0;
-}
-
-GLOBAL(int)
-jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
-                                   const int *jpeg_natural_order_start, int Sl,
-                                   int Al, JCOEF *absvalues, size_t *bits)
-{
-  return 0;
-}
diff --git a/src/third_party/libjpeg-turbo/simd/powerpc/jsimd_altivec.h b/src/third_party/libjpeg-turbo/simd/powerpc/jsimd_altivec.h
deleted file mode 100644
index e8bdb06..0000000
--- a/src/third_party/libjpeg-turbo/simd/powerpc/jsimd_altivec.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * AltiVec optimizations for libjpeg-turbo
- *
- * Copyright (C) 2014-2015, D. R. Commander.  All Rights Reserved.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#define JPEG_INTERNALS
-#include "../../jinclude.h"
-#include "../../jpeglib.h"
-#include "../../jsimd.h"
-#include "../../jdct.h"
-#include "../../jsimddct.h"
-#include "../jsimd.h"
-#include <altivec.h>
-
-
-/* Common code */
-
-#define __4X(a)      a, a, a, a
-#define __4X2(a, b)  a, b, a, b, a, b, a, b
-#define __8X(a)      __4X(a), __4X(a)
-#define __16X(a)     __8X(a), __8X(a)
-
-#define TRANSPOSE(row, col) { \
-  __vector short row04l, row04h, row15l, row15h, \
-                 row26l, row26h, row37l, row37h; \
-  __vector short col01e, col01o, col23e, col23o, \
-                 col45e, col45o, col67e, col67o; \
-  \
-                                       /* transpose coefficients (phase 1) */ \
-  row04l = vec_mergeh(row##0, row##4); /* row04l=(00 40 01 41 02 42 03 43) */ \
-  row04h = vec_mergel(row##0, row##4); /* row04h=(04 44 05 45 06 46 07 47) */ \
-  row15l = vec_mergeh(row##1, row##5); /* row15l=(10 50 11 51 12 52 13 53) */ \
-  row15h = vec_mergel(row##1, row##5); /* row15h=(14 54 15 55 16 56 17 57) */ \
-  row26l = vec_mergeh(row##2, row##6); /* row26l=(20 60 21 61 22 62 23 63) */ \
-  row26h = vec_mergel(row##2, row##6); /* row26h=(24 64 25 65 26 66 27 67) */ \
-  row37l = vec_mergeh(row##3, row##7); /* row37l=(30 70 31 71 32 72 33 73) */ \
-  row37h = vec_mergel(row##3, row##7); /* row37h=(34 74 35 75 36 76 37 77) */ \
-  \
-                                       /* transpose coefficients (phase 2) */ \
-  col01e = vec_mergeh(row04l, row26l); /* col01e=(00 20 40 60 01 21 41 61) */ \
-  col23e = vec_mergel(row04l, row26l); /* col23e=(02 22 42 62 03 23 43 63) */ \
-  col45e = vec_mergeh(row04h, row26h); /* col45e=(04 24 44 64 05 25 45 65) */ \
-  col67e = vec_mergel(row04h, row26h); /* col67e=(06 26 46 66 07 27 47 67) */ \
-  col01o = vec_mergeh(row15l, row37l); /* col01o=(10 30 50 70 11 31 51 71) */ \
-  col23o = vec_mergel(row15l, row37l); /* col23o=(12 32 52 72 13 33 53 73) */ \
-  col45o = vec_mergeh(row15h, row37h); /* col45o=(14 34 54 74 15 35 55 75) */ \
-  col67o = vec_mergel(row15h, row37h); /* col67o=(16 36 56 76 17 37 57 77) */ \
-  \
-                                       /* transpose coefficients (phase 3) */ \
-  col##0 = vec_mergeh(col01e, col01o); /* col0=(00 10 20 30 40 50 60 70) */ \
-  col##1 = vec_mergel(col01e, col01o); /* col1=(01 11 21 31 41 51 61 71) */ \
-  col##2 = vec_mergeh(col23e, col23o); /* col2=(02 12 22 32 42 52 62 72) */ \
-  col##3 = vec_mergel(col23e, col23o); /* col3=(03 13 23 33 43 53 63 73) */ \
-  col##4 = vec_mergeh(col45e, col45o); /* col4=(04 14 24 34 44 54 64 74) */ \
-  col##5 = vec_mergel(col45e, col45o); /* col5=(05 15 25 35 45 55 65 75) */ \
-  col##6 = vec_mergeh(col67e, col67o); /* col6=(06 16 26 36 46 56 66 76) */ \
-  col##7 = vec_mergel(col67e, col67o); /* col7=(07 17 27 37 47 57 67 77) */ \
-}
-
-#ifndef min
-#define min(a, b)  ((a) < (b) ? (a) : (b))
-#endif
-
-
-/* Macros to abstract big/little endian bit twiddling */
-
-#if __BIG_ENDIAN__
-
-#define VEC_LD(a, b)     vec_ld(a, b)
-#define VEC_ST(a, b, c)  vec_st(a, b, c)
-#define VEC_UNPACKHU(a)  vec_mergeh(pb_zero, a)
-#define VEC_UNPACKLU(a)  vec_mergel(pb_zero, a)
-
-#else
-
-#define VEC_LD(a, b)     vec_vsx_ld(a, b)
-#define VEC_ST(a, b, c)  vec_vsx_st(a, b, c)
-#define VEC_UNPACKHU(a)  vec_mergeh(a, pb_zero)
-#define VEC_UNPACKLU(a)  vec_mergel(a, pb_zero)
-
-#endif
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-avx2.asm
index 5fa3848..ffb527d 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-avx2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright (C) 2009, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -59,9 +58,9 @@
 
     mov         rsi, r12
     mov         ecx, r13d
-    mov         rdi, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rsi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rsi+2*SIZEOF_JSAMPARRAY]
+    mov         rdip, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsi+2*SIZEOF_JSAMPARRAY]
     lea         rdi, [rdi+rcx*SIZEOF_JSAMPROW]
     lea         rbx, [rbx+rcx*SIZEOF_JSAMPROW]
     lea         rdx, [rdx+rcx*SIZEOF_JSAMPROW]
@@ -79,10 +78,10 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr0
-    mov         rbx, JSAMPROW [rbx]     ; outptr1
-    mov         rdx, JSAMPROW [rdx]     ; outptr2
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr0
+    mov         rbxp, JSAMPROW [rbx]    ; outptr1
+    mov         rdxp, JSAMPROW [rdx]    ; outptr2
 
     cmp         rcx, byte SIZEOF_YMMWORD
     jae         near .columnloop
@@ -96,12 +95,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         rcx, byte SIZEOF_BYTE
-    movzx       rax, BYTE [rsi+rcx]
+    movzx       rax, byte [rsi+rcx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         rcx, byte SIZEOF_WORD
-    movzx       rdx, WORD [rsi+rcx]
+    movzx       rdx, word [rsi+rcx]
     shl         rax, WORD_BIT
     or          rax, rdx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-sse2.asm
index b1486c0..af70ed6 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jccolext-sse2.asm
@@ -2,6 +2,7 @@
 ; jccolext.asm - colorspace conversion (64-bit SSE2)
 ;
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -12,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -58,9 +57,9 @@
 
     mov         rsi, r12
     mov         ecx, r13d
-    mov         rdi, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rsi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rsi+2*SIZEOF_JSAMPARRAY]
+    mov         rdip, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsi+2*SIZEOF_JSAMPARRAY]
     lea         rdi, [rdi+rcx*SIZEOF_JSAMPROW]
     lea         rbx, [rbx+rcx*SIZEOF_JSAMPROW]
     lea         rdx, [rdx+rcx*SIZEOF_JSAMPROW]
@@ -78,10 +77,10 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr0
-    mov         rbx, JSAMPROW [rbx]     ; outptr1
-    mov         rdx, JSAMPROW [rdx]     ; outptr2
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr0
+    mov         rbxp, JSAMPROW [rbx]    ; outptr1
+    mov         rdxp, JSAMPROW [rdx]    ; outptr2
 
     cmp         rcx, byte SIZEOF_XMMWORD
     jae         near .columnloop
@@ -95,12 +94,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         rcx, byte SIZEOF_BYTE
-    movzx       rax, BYTE [rsi+rcx]
+    movzx       rax, byte [rsi+rcx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         rcx, byte SIZEOF_WORD
-    movzx       rdx, WORD [rsi+rcx]
+    movzx       rdx, word [rsi+rcx]
     shl         rax, WORD_BIT
     or          rax, rdx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-avx2.asm
index f9f4be0..16b7829 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-sse2.asm
index 3e46601..e2955c2 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jccolor-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-avx2.asm
index 0ec2410..591255b 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-avx2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-sse2.asm
index edf9222..e389904 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcgray-sse2.asm
@@ -12,8 +12,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-avx2.asm
index 79e2aa0..ddcc2c0 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-avx2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright (C) 2011, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -59,7 +58,7 @@
 
     mov         rsi, r12
     mov         ecx, r13d
-    mov         rdi, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
+    mov         rdip, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
     lea         rdi, [rdi+rcx*SIZEOF_JSAMPROW]
 
     pop         rcx
@@ -73,8 +72,8 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr0
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr0
 
     cmp         rcx, byte SIZEOF_YMMWORD
     jae         near .columnloop
@@ -88,12 +87,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         rcx, byte SIZEOF_BYTE
-    movzx       rax, BYTE [rsi+rcx]
+    movzx       rax, byte [rsi+rcx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         rcx, byte SIZEOF_WORD
-    movzx       rdx, WORD [rsi+rcx]
+    movzx       rdx, word [rsi+rcx]
     shl         rax, WORD_BIT
     or          rax, rdx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-sse2.asm
index 9c3ae5e..f1d399a 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcgryext-sse2.asm
@@ -2,6 +2,7 @@
 ; jcgryext.asm - grayscale colorspace conversion (64-bit SSE2)
 ;
 ; Copyright (C) 2011, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -12,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -58,7 +57,7 @@
 
     mov         rsi, r12
     mov         ecx, r13d
-    mov         rdi, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
+    mov         rdip, JSAMPARRAY [rsi+0*SIZEOF_JSAMPARRAY]
     lea         rdi, [rdi+rcx*SIZEOF_JSAMPROW]
 
     pop         rcx
@@ -72,8 +71,8 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr0
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr0
 
     cmp         rcx, byte SIZEOF_XMMWORD
     jae         near .columnloop
@@ -87,12 +86,12 @@
     test        cl, SIZEOF_BYTE
     jz          short .column_ld2
     sub         rcx, byte SIZEOF_BYTE
-    movzx       rax, BYTE [rsi+rcx]
+    movzx       rax, byte [rsi+rcx]
 .column_ld2:
     test        cl, SIZEOF_WORD
     jz          short .column_ld4
     sub         rcx, byte SIZEOF_WORD
-    movzx       rdx, WORD [rsi+rcx]
+    movzx       rdx, word [rsi+rcx]
     shl         rax, WORD_BIT
     or          rax, rdx
 .column_ld4:
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jchuff-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jchuff-sse2.asm
index 1b091ad..0072028 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jchuff-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jchuff-sse2.asm
@@ -1,8 +1,9 @@
 ;
 ; jchuff-sse2.asm - Huffman entropy encoding (64-bit SSE2)
 ;
-; Copyright (C) 2009-2011, 2014-2016, D. R. Commander.
+; Copyright (C) 2009-2011, 2014-2016, 2019, D. R. Commander.
 ; Copyright (C) 2015, Matthieu Darbois.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -15,13 +16,25 @@
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
 ; This file contains an SSE2 implementation for Huffman coding of one block.
-; The following code is based directly on jchuff.c; see jchuff.c for more
-; details.
-;
-; [TAB8]
+; The following code is based on jchuff.c; see jchuff.c for more details.
 
 %include "jsimdext.inc"
 
+struc working_state
+.next_output_byte:   resp 1     ; => next byte to write in buffer
+.free_in_buffer:     resp 1     ; # of byte spaces remaining in buffer
+.cur.put_buffer.simd resq 1     ; current bit accumulation buffer
+.cur.free_bits       resd 1     ; # of bits available in it
+.cur.last_dc_val     resd 4     ; last DC coef for each component
+.cinfo:              resp 1     ; dump_buffer needs access to this
+endstruc
+
+struc c_derived_tbl
+.ehufco:             resd 256   ; code for each symbol
+.ehufsi:             resb 256   ; length of code for each symbol
+; If no code has been allocated for a symbol S, ehufsi[S] contains 0
+endstruc
+
 ; --------------------------------------------------------------------------
     SECTION     SEG_CONST
 
@@ -30,134 +43,137 @@
 
 EXTN(jconst_huff_encode_one_block):
 
-%include "jpeg_nbits_table.inc"
+jpeg_mask_bits dd 0x0000, 0x0001, 0x0003, 0x0007
+               dd 0x000f, 0x001f, 0x003f, 0x007f
+               dd 0x00ff, 0x01ff, 0x03ff, 0x07ff
+               dd 0x0fff, 0x1fff, 0x3fff, 0x7fff
 
     alignz      32
 
+times 1 << 14 db 15
+times 1 << 13 db 14
+times 1 << 12 db 13
+times 1 << 11 db 12
+times 1 << 10 db 11
+times 1 <<  9 db 10
+times 1 <<  8 db  9
+times 1 <<  7 db  8
+times 1 <<  6 db  7
+times 1 <<  5 db  6
+times 1 <<  4 db  5
+times 1 <<  3 db  4
+times 1 <<  2 db  3
+times 1 <<  1 db  2
+times 1 <<  0 db  1
+times 1       db  0
+jpeg_nbits_table:
+times 1       db  0
+times 1 <<  0 db  1
+times 1 <<  1 db  2
+times 1 <<  2 db  3
+times 1 <<  3 db  4
+times 1 <<  4 db  5
+times 1 <<  5 db  6
+times 1 <<  6 db  7
+times 1 <<  7 db  8
+times 1 <<  8 db  9
+times 1 <<  9 db 10
+times 1 << 10 db 11
+times 1 << 11 db 12
+times 1 << 12 db 13
+times 1 << 13 db 14
+times 1 << 14 db 15
+
+    alignz      32
+
+%define NBITS(x)      nbits_base + x
+%define MASK_BITS(x)  NBITS((x) * 4) + (jpeg_mask_bits - jpeg_nbits_table)
+
 ; --------------------------------------------------------------------------
     SECTION     SEG_TEXT
     BITS        64
 
-; These macros perform the same task as the emit_bits() function in the
-; original libjpeg code.  In addition to reducing overhead by explicitly
-; inlining the code, additional performance is achieved by taking into
-; account the size of the bit buffer and waiting until it is almost full
-; before emptying it.  This mostly benefits 64-bit platforms, since 6
-; bytes can be stored in a 64-bit bit buffer before it has to be emptied.
+; Shorthand used to describe SIMD operations:
+; wN:  xmmN treated as eight signed 16-bit values
+; wN[i]:  perform the same operation on all eight signed 16-bit values, i=0..7
+; bN:  xmmN treated as 16 unsigned 8-bit values
+; bN[i]:  perform the same operation on all 16 unsigned 8-bit values, i=0..15
+; Contents of SIMD registers are shown in memory order.
 
-%macro EMIT_BYTE 0
-    sub         put_bits, 8             ; put_bits -= 8;
-    mov         rdx, put_buffer
-    mov         ecx, put_bits
-    shr         rdx, cl                 ; c = (JOCTET)GETJOCTET(put_buffer >> put_bits);
-    mov         byte [buffer], dl       ; *buffer++ = c;
-    add         buffer, 1
-    cmp         dl, 0xFF                ; need to stuff a zero byte?
-    jne         %%.EMIT_BYTE_END
-    mov         byte [buffer], 0        ; *buffer++ = 0;
-    add         buffer, 1
-%%.EMIT_BYTE_END:
-%endmacro
+; Fill the bit buffer to capacity with the leading bits from code, then output
+; the bit buffer and put the remaining bits from code into the bit buffer.
+;
+; Usage:
+; code - contains the bits to shift into the bit buffer (LSB-aligned)
+; %1 - the label to which to jump when the macro completes
+; %2 (optional) - extra instructions to execute after nbits has been set
+;
+; Upon completion, free_bits will be set to the number of remaining bits from
+; code, and put_buffer will contain those remaining bits.  temp and code will
+; be clobbered.
+;
+; This macro encodes any 0xFF bytes as 0xFF 0x00, as does the EMIT_BYTE()
+; macro in jchuff.c.
 
-%macro PUT_BITS 1
-    add         put_bits, ecx           ; put_bits += size;
-    shl         put_buffer, cl          ; put_buffer = (put_buffer << size);
-    or          put_buffer, %1
-%endmacro
-
-%macro CHECKBUF31 0
-    cmp         put_bits, 32            ; if (put_bits > 31) {
-    jl          %%.CHECKBUF31_END
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-%%.CHECKBUF31_END:
-%endmacro
-
-%macro CHECKBUF47 0
-    cmp         put_bits, 48            ; if (put_bits > 47) {
-    jl          %%.CHECKBUF47_END
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-    EMIT_BYTE
-%%.CHECKBUF47_END:
-%endmacro
-
-%macro EMIT_BITS 2
-    CHECKBUF47
-    mov         ecx, %2
-    PUT_BITS    %1
-%endmacro
-
-%macro kloop_prepare 37                 ;(ko, jno0, ..., jno31, xmm0, xmm1, xmm2, xmm3)
-    pxor        xmm8, xmm8              ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm9, xmm9              ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm10, xmm10            ; __m128i neg = _mm_setzero_si128();
-    pxor        xmm11, xmm11            ; __m128i neg = _mm_setzero_si128();
-    pinsrw      %34, word [r12 + %2  * SIZEOF_WORD], 0  ; xmm_shadow[0] = block[jno0];
-    pinsrw      %35, word [r12 + %10 * SIZEOF_WORD], 0  ; xmm_shadow[8] = block[jno8];
-    pinsrw      %36, word [r12 + %18 * SIZEOF_WORD], 0  ; xmm_shadow[16] = block[jno16];
-    pinsrw      %37, word [r12 + %26 * SIZEOF_WORD], 0  ; xmm_shadow[24] = block[jno24];
-    pinsrw      %34, word [r12 + %3  * SIZEOF_WORD], 1  ; xmm_shadow[1] = block[jno1];
-    pinsrw      %35, word [r12 + %11 * SIZEOF_WORD], 1  ; xmm_shadow[9] = block[jno9];
-    pinsrw      %36, word [r12 + %19 * SIZEOF_WORD], 1  ; xmm_shadow[17] = block[jno17];
-    pinsrw      %37, word [r12 + %27 * SIZEOF_WORD], 1  ; xmm_shadow[25] = block[jno25];
-    pinsrw      %34, word [r12 + %4  * SIZEOF_WORD], 2  ; xmm_shadow[2] = block[jno2];
-    pinsrw      %35, word [r12 + %12 * SIZEOF_WORD], 2  ; xmm_shadow[10] = block[jno10];
-    pinsrw      %36, word [r12 + %20 * SIZEOF_WORD], 2  ; xmm_shadow[18] = block[jno18];
-    pinsrw      %37, word [r12 + %28 * SIZEOF_WORD], 2  ; xmm_shadow[26] = block[jno26];
-    pinsrw      %34, word [r12 + %5  * SIZEOF_WORD], 3  ; xmm_shadow[3] = block[jno3];
-    pinsrw      %35, word [r12 + %13 * SIZEOF_WORD], 3  ; xmm_shadow[11] = block[jno11];
-    pinsrw      %36, word [r12 + %21 * SIZEOF_WORD], 3  ; xmm_shadow[19] = block[jno19];
-    pinsrw      %37, word [r12 + %29 * SIZEOF_WORD], 3  ; xmm_shadow[27] = block[jno27];
-    pinsrw      %34, word [r12 + %6  * SIZEOF_WORD], 4  ; xmm_shadow[4] = block[jno4];
-    pinsrw      %35, word [r12 + %14 * SIZEOF_WORD], 4  ; xmm_shadow[12] = block[jno12];
-    pinsrw      %36, word [r12 + %22 * SIZEOF_WORD], 4  ; xmm_shadow[20] = block[jno20];
-    pinsrw      %37, word [r12 + %30 * SIZEOF_WORD], 4  ; xmm_shadow[28] = block[jno28];
-    pinsrw      %34, word [r12 + %7  * SIZEOF_WORD], 5  ; xmm_shadow[5] = block[jno5];
-    pinsrw      %35, word [r12 + %15 * SIZEOF_WORD], 5  ; xmm_shadow[13] = block[jno13];
-    pinsrw      %36, word [r12 + %23 * SIZEOF_WORD], 5  ; xmm_shadow[21] = block[jno21];
-    pinsrw      %37, word [r12 + %31 * SIZEOF_WORD], 5  ; xmm_shadow[29] = block[jno29];
-    pinsrw      %34, word [r12 + %8  * SIZEOF_WORD], 6  ; xmm_shadow[6] = block[jno6];
-    pinsrw      %35, word [r12 + %16 * SIZEOF_WORD], 6  ; xmm_shadow[14] = block[jno14];
-    pinsrw      %36, word [r12 + %24 * SIZEOF_WORD], 6  ; xmm_shadow[22] = block[jno22];
-    pinsrw      %37, word [r12 + %32 * SIZEOF_WORD], 6  ; xmm_shadow[30] = block[jno30];
-    pinsrw      %34, word [r12 + %9  * SIZEOF_WORD], 7  ; xmm_shadow[7] = block[jno7];
-    pinsrw      %35, word [r12 + %17 * SIZEOF_WORD], 7  ; xmm_shadow[15] = block[jno15];
-    pinsrw      %36, word [r12 + %25 * SIZEOF_WORD], 7  ; xmm_shadow[23] = block[jno23];
-%if %1 != 32
-    pinsrw      %37, word [r12 + %33 * SIZEOF_WORD], 7  ; xmm_shadow[31] = block[jno31];
-%else
-    pinsrw      %37, ebx, 7             ; xmm_shadow[31] = block[jno31];
-%endif
-    pcmpgtw     xmm8, %34               ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm9, %35               ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm10, %36              ; neg = _mm_cmpgt_epi16(neg, x1);
-    pcmpgtw     xmm11, %37              ; neg = _mm_cmpgt_epi16(neg, x1);
-    paddw       %34, xmm8               ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %35, xmm9               ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %36, xmm10              ; x1 = _mm_add_epi16(x1, neg);
-    paddw       %37, xmm11              ; x1 = _mm_add_epi16(x1, neg);
-    pxor        %34, xmm8               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %35, xmm9               ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %36, xmm10              ; x1 = _mm_xor_si128(x1, neg);
-    pxor        %37, xmm11              ; x1 = _mm_xor_si128(x1, neg);
-    pxor        xmm8, %34               ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm9, %35               ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm10, %36              ; neg = _mm_xor_si128(neg, x1);
-    pxor        xmm11, %37              ; neg = _mm_xor_si128(neg, x1);
-    movdqa      XMMWORD [t1 + %1 * SIZEOF_WORD], %34           ; _mm_storeu_si128((__m128i *)(t1 + ko), x1);
-    movdqa      XMMWORD [t1 + (%1 + 8) * SIZEOF_WORD], %35     ; _mm_storeu_si128((__m128i *)(t1 + ko + 8), x1);
-    movdqa      XMMWORD [t1 + (%1 + 16) * SIZEOF_WORD], %36    ; _mm_storeu_si128((__m128i *)(t1 + ko + 16), x1);
-    movdqa      XMMWORD [t1 + (%1 + 24) * SIZEOF_WORD], %37    ; _mm_storeu_si128((__m128i *)(t1 + ko + 24), x1);
-    movdqa      XMMWORD [t2 + %1 * SIZEOF_WORD], xmm8          ; _mm_storeu_si128((__m128i *)(t2 + ko), neg);
-    movdqa      XMMWORD [t2 + (%1 + 8) * SIZEOF_WORD], xmm9    ; _mm_storeu_si128((__m128i *)(t2 + ko + 8), neg);
-    movdqa      XMMWORD [t2 + (%1 + 16) * SIZEOF_WORD], xmm10  ; _mm_storeu_si128((__m128i *)(t2 + ko + 16), neg);
-    movdqa      XMMWORD [t2 + (%1 + 24) * SIZEOF_WORD], xmm11  ; _mm_storeu_si128((__m128i *)(t2 + ko + 24), neg);
+%macro EMIT_QWORD 1-2
+    add         nbitsb, free_bitsb      ; nbits += free_bits;
+    neg         free_bitsb              ; free_bits = -free_bits;
+    mov         tempd, code             ; temp = code;
+    shl         put_buffer, nbitsb      ; put_buffer <<= nbits;
+    mov         nbitsb, free_bitsb      ; nbits = free_bits;
+    neg         free_bitsb              ; free_bits = -free_bits;
+    shr         tempd, nbitsb           ; temp >>= nbits;
+    or          tempq, put_buffer       ; temp |= put_buffer;
+    movq        xmm0, tempq             ; xmm0.u64 = { temp, 0 };
+    bswap       tempq                   ; temp = htonl(temp);
+    mov         put_buffer, codeq       ; put_buffer = code;
+    pcmpeqb     xmm0, xmm1              ; b0[i] = (b0[i] == 0xFF ? 0xFF : 0);
+    %2
+    pmovmskb    code, xmm0              ; code = 0;  code |= ((b0[i] >> 7) << i);
+    mov         qword [buffer], tempq   ; memcpy(buffer, &temp, 8);
+                                        ; (speculative; will be overwritten if
+                                        ; code contains any 0xFF bytes)
+    add         free_bitsb, 64          ; free_bits += 64;
+    add         bufferp, 8              ; buffer += 8;
+    test        code, code              ; if (code == 0)  /* No 0xFF bytes */
+    jz          %1                      ;   return;
+    ; Execute the equivalent of the EMIT_BYTE() macro in jchuff.c for all 8
+    ; bytes in the qword.
+    cmp         tempb, 0xFF             ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer-7], 0      ; buffer[-7] = 0;
+    sbb         bufferp, 6              ; buffer -= (6 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], temph    ; buffer[0] = temp[1];
+    cmp         temph, 0xFF             ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    shr         tempq, 16               ; temp >>= 16;
+    mov         byte [buffer], tempb    ; buffer[0] = temp[0];
+    cmp         tempb, 0xFF             ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], temph    ; buffer[0] = temp[1];
+    cmp         temph, 0xFF             ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    shr         tempq, 16               ; temp >>= 16;
+    mov         byte [buffer], tempb    ; buffer[0] = temp[0];
+    cmp         tempb, 0xFF             ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], temph    ; buffer[0] = temp[1];
+    cmp         temph, 0xFF             ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    shr         tempd, 16               ; temp >>= 16;
+    mov         byte [buffer], tempb    ; buffer[0] = temp[0];
+    cmp         tempb, 0xFF             ; Set CF if temp[0] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[0] < 0xFF ? 1 : 0));
+    mov         byte [buffer], temph    ; buffer[0] = temp[1];
+    cmp         temph, 0xFF             ; Set CF if temp[1] < 0xFF
+    mov         byte [buffer+1], 0      ; buffer[1] = 0;
+    sbb         bufferp, -2             ; buffer -= (-2 + (temp[1] < 0xFF ? 1 : 0));
+    jmp         %1                      ; return;
 %endmacro
 
 ;
@@ -168,181 +184,399 @@
 ;                                  JCOEFPTR block, int last_dc_val,
 ;                                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
 ;
+; NOTES:
+; When shuffling data, we try to avoid pinsrw as much as possible, since it is
+; slow on many CPUs.  Its reciprocal throughput (issue latency) is 1 even on
+; modern CPUs, so chains of pinsrw instructions (even with different outputs)
+; can limit performance.  pinsrw is a VectorPath instruction on AMD K8 and
+; requires 2 µops (with memory operand) on Intel.  In either case, only one
+; pinsrw instruction can be decoded per cycle (and nothing else if they are
+; back-to-back), so out-of-order execution cannot be used to work around long
+; pinsrw chains (though for Sandy Bridge and later, this may be less of a
+; problem if the code runs from the µop cache.)
+;
+; We use tzcnt instead of bsf without checking for support.  The instruction is
+; executed as bsf on CPUs that don't support tzcnt (encoding is equivalent to
+; rep bsf.)  The destination (first) operand of bsf (and tzcnt on some CPUs) is
+; an input dependency (although the behavior is not formally defined, Intel
+; CPUs usually leave the destination unmodified if the source is zero.)  This
+; can prevent out-of-order execution, so we clear the destination before
+; invoking tzcnt.
+;
+; Initial register allocation
+; rax - buffer
+; rbx - temp
+; rcx - nbits
+; rdx - block --> free_bits
+; rsi - nbits_base
+; rdi - t
+; rbp - code
+; r8  - dctbl --> code_temp
+; r9  - actbl
+; r10 - state
+; r11 - index
+; r12 - put_buffer
 
-; r10 = working_state *state
-; r11 = JOCTET *buffer
-; r12 = JCOEFPTR block
-; r13d = int last_dc_val
-; r14 = c_derived_tbl *dctbl
-; r15 = c_derived_tbl *actbl
+%define buffer       rax
+%ifdef WIN64
+%define bufferp      rax
+%else
+%define bufferp      raxp
+%endif
+%define tempq        rbx
+%define tempd        ebx
+%define tempb        bl
+%define temph        bh
+%define nbitsq       rcx
+%define nbits        ecx
+%define nbitsb       cl
+%define block        rdx
+%define nbits_base   rsi
+%define t            rdi
+%define td           edi
+%define codeq        rbp
+%define code         ebp
+%define dctbl        r8
+%define actbl        r9
+%define state        r10
+%define index        r11
+%define indexd       r11d
+%define put_buffer   r12
+%define put_bufferd  r12d
 
-%define t1          rbp - (DCTSIZE2 * SIZEOF_WORD)
-%define t2          t1 - (DCTSIZE2 * SIZEOF_WORD)
-%define put_buffer  r8
-%define put_bits    r9d
-%define buffer      rax
+; Step 1: Re-arrange input data according to jpeg_natural_order
+; xx 01 02 03 04 05 06 07      xx 01 08 16 09 02 03 10
+; 08 09 10 11 12 13 14 15      17 24 32 25 18 11 04 05
+; 16 17 18 19 20 21 22 23      12 19 26 33 40 48 41 34
+; 24 25 26 27 28 29 30 31 ==>  27 20 13 06 07 14 21 28
+; 32 33 34 35 36 37 38 39      35 42 49 56 57 50 43 36
+; 40 41 42 43 44 45 46 47      29 22 15 23 30 37 44 51
+; 48 49 50 51 52 53 54 55      58 59 52 45 38 31 39 46
+; 56 57 58 59 60 61 62 63      53 60 61 54 47 55 62 63
 
     align       32
     GLOBAL_FUNCTION(jsimd_huff_encode_one_block_sse2)
 
 EXTN(jsimd_huff_encode_one_block_sse2):
-    push        rbp
-    mov         rax, rsp                     ; rax = original rbp
-    sub         rsp, byte 4
-    and         rsp, byte (-SIZEOF_XMMWORD)  ; align to 128 bits
-    mov         [rsp], rax
-    mov         rbp, rsp                     ; rbp = aligned rbp
-    lea         rsp, [t2]
-    push_xmm    4
-    collect_args 6
+
+%ifdef WIN64
+
+; rcx = working_state *state
+; rdx = JOCTET *buffer
+; r8 = JCOEFPTR block
+; r9 = int last_dc_val
+; [rax+48] = c_derived_tbl *dctbl
+; [rax+56] = c_derived_tbl *actbl
+
+                                                          ;X: X = code stream
+    mov         buffer, rdx
+    mov         block, r8
+    movups      xmm3, XMMWORD [block + 0 * SIZEOF_WORD]   ;D: w3 = xx 01 02 03 04 05 06 07
     push        rbx
+    push        rbp
+    movdqa      xmm0, xmm3                                ;A: w0 = xx 01 02 03 04 05 06 07
+    push        rsi
+    push        rdi
+    push        r12
+    movups      xmm1, XMMWORD [block + 8 * SIZEOF_WORD]   ;B: w1 = 08 09 10 11 12 13 14 15
+    mov         state, rcx
+    movsx       code, word [block]                        ;Z:     code = block[0];
+    pxor        xmm4, xmm4                                ;A: w4[i] = 0;
+    sub         code, r9d                                 ;Z:     code -= last_dc_val;
+    mov         dctbl, POINTER [rsp+6*8+4*8]
+    mov         actbl, POINTER [rsp+6*8+5*8]
+    punpckldq   xmm0, xmm1                                ;A: w0 = xx 01 08 09 02 03 10 11
+    lea         nbits_base, [rel jpeg_nbits_table]
+    add         rsp, -DCTSIZE2 * SIZEOF_WORD
+    mov         t, rsp
 
-    mov         buffer, r11                  ; r11 is now sratch
+%else
 
-    mov         put_buffer, MMWORD [r10+16]  ; put_buffer = state->cur.put_buffer;
-    mov         put_bits,    DWORD [r10+24]  ; put_bits = state->cur.put_bits;
-    push        r10                          ; r10 is now scratch
+; rdi = working_state *state
+; rsi = JOCTET *buffer
+; rdx = JCOEFPTR block
+; rcx = int last_dc_val
+; r8 = c_derived_tbl *dctbl
+; r9 = c_derived_tbl *actbl
 
-    ; Encode the DC coefficient difference per section F.1.2.1
-    movsx       edi, word [r12]         ; temp = temp2 = block[0] - last_dc_val;
-    sub         edi, r13d               ; r13 is not used anymore
-    mov         ebx, edi
+                                                          ;X: X = code stream
+    movups      xmm3, XMMWORD [block + 0 * SIZEOF_WORD]   ;D: w3 = xx 01 02 03 04 05 06 07
+    push        rbx
+    push        rbp
+    movdqa      xmm0, xmm3                                ;A: w0 = xx 01 02 03 04 05 06 07
+    push        r12
+    mov         state, rdi
+    mov         buffer, rsi
+    movups      xmm1, XMMWORD [block + 8 * SIZEOF_WORD]   ;B: w1 = 08 09 10 11 12 13 14 15
+    movsx       codeq, word [block]                       ;Z:     code = block[0];
+    lea         nbits_base, [rel jpeg_nbits_table]
+    pxor        xmm4, xmm4                                ;A: w4[i] = 0;
+    sub         codeq, rcx                                ;Z:     code -= last_dc_val;
+    punpckldq   xmm0, xmm1                                ;A: w0 = xx 01 08 09 02 03 10 11
+    lea         t, [rsp - DCTSIZE2 * SIZEOF_WORD]         ;   use red zone for t_
 
-    ; This is a well-known technique for obtaining the absolute value
-    ; without a branch.  It is derived from an assembly language technique
-    ; presented in "How to Optimize for the Pentium Processors",
-    ; Copyright (c) 1996, 1997 by Agner Fog.
-    mov         esi, edi
-    sar         esi, 31                 ; temp3 = temp >> (CHAR_BIT * sizeof(int) - 1);
-    xor         edi, esi                ; temp ^= temp3;
-    sub         edi, esi                ; temp -= temp3;
+%endif
 
-    ; For a negative input, want temp2 = bitwise complement of abs(input)
-    ; This code assumes we are on a two's complement machine
-    add         ebx, esi                ; temp2 += temp3;
+    pshuflw     xmm0, xmm0, 11001001b                     ;A: w0 = 01 08 xx 09 02 03 10 11
+    pinsrw      xmm0, word [block + 16 * SIZEOF_WORD], 2  ;A: w0 = 01 08 16 09 02 03 10 11
+    punpckhdq   xmm3, xmm1                                ;D: w3 = 04 05 12 13 06 07 14 15
+    punpcklqdq  xmm1, xmm3                                ;B: w1 = 08 09 10 11 04 05 12 13
+    pinsrw      xmm0, word [block + 17 * SIZEOF_WORD], 7  ;A: w0 = 01 08 16 09 02 03 10 17
+                                                          ;A:      (Row 0, offset 1)
+    pcmpgtw     xmm4, xmm0                                ;A: w4[i] = (w0[i] < 0 ? -1 : 0);
+    paddw       xmm0, xmm4                                ;A: w0[i] += w4[i];
+    movaps      XMMWORD [t + 0 * SIZEOF_WORD], xmm0       ;A: t[i] = w0[i];
 
-    ; Find the number of bits needed for the magnitude of the coefficient
-    lea         r11, [rel jpeg_nbits_table]
-    movzx       rdi, byte [r11 + rdi]         ; nbits = JPEG_NBITS(temp);
-    ; Emit the Huffman-coded symbol for the number of bits
-    mov         r11d,  INT [r14 + rdi * 4]    ; code = dctbl->ehufco[nbits];
-    movzx       esi, byte [r14 + rdi + 1024]  ; size = dctbl->ehufsi[nbits];
-    EMIT_BITS   r11, esi                      ; EMIT_BITS(code, size)
+    movq        xmm2, qword [block + 24 * SIZEOF_WORD]    ;B: w2 = 24 25 26 27 -- -- -- --
+    pshuflw     xmm2, xmm2, 11011000b                     ;B: w2 = 24 26 25 27 -- -- -- --
+    pslldq      xmm1, 1 * SIZEOF_WORD                     ;B: w1 = -- 08 09 10 11 04 05 12
+    movups      xmm5, XMMWORD [block + 48 * SIZEOF_WORD]  ;H: w5 = 48 49 50 51 52 53 54 55
+    movsd       xmm1, xmm2                                ;B: w1 = 24 26 25 27 11 04 05 12
+    punpcklqdq  xmm2, xmm5                                ;C: w2 = 24 26 25 27 48 49 50 51
+    pinsrw      xmm1, word [block + 32 * SIZEOF_WORD], 1  ;B: w1 = 24 32 25 27 11 04 05 12
+    pxor        xmm4, xmm4                                ;A: w4[i] = 0;
+    psrldq      xmm3, 2 * SIZEOF_WORD                     ;D: w3 = 12 13 06 07 14 15 -- --
+    pcmpeqw     xmm0, xmm4                                ;A: w0[i] = (w0[i] == 0 ? -1 : 0);
+    pinsrw      xmm1, word [block + 18 * SIZEOF_WORD], 3  ;B: w1 = 24 32 25 18 11 04 05 12
+                                                          ;        (Row 1, offset 1)
+    pcmpgtw     xmm4, xmm1                                ;B: w4[i] = (w1[i] < 0 ? -1 : 0);
+    paddw       xmm1, xmm4                                ;B: w1[i] += w4[i];
+    movaps      XMMWORD [t + 8 * SIZEOF_WORD], xmm1       ;B: t[i+8] = w1[i];
+    pxor        xmm4, xmm4                                ;B: w4[i] = 0;
+    pcmpeqw     xmm1, xmm4                                ;B: w1[i] = (w1[i] == 0 ? -1 : 0);
 
-    ; Mask off any extra bits in code
-    mov         esi, 1
-    mov         ecx, edi
-    shl         esi, cl
-    dec         esi
-    and         ebx, esi                ; temp2 &= (((JLONG)1)<<nbits) - 1;
+    packsswb    xmm0, xmm1                                ;AB: b0[i] = w0[i], b0[i+8] = w1[i]
+                                                          ;    w/ signed saturation
 
-    ; Emit that number of bits of the value, if positive,
-    ; or the complement of its magnitude, if negative.
-    EMIT_BITS   rbx, edi                ; EMIT_BITS(temp2, nbits)
+    pinsrw      xmm3, word [block + 20 * SIZEOF_WORD], 0  ;D: w3 = 20 13 06 07 14 15 -- --
+    pinsrw      xmm3, word [block + 21 * SIZEOF_WORD], 5  ;D: w3 = 20 13 06 07 14 21 -- --
+    pinsrw      xmm3, word [block + 28 * SIZEOF_WORD], 6  ;D: w3 = 20 13 06 07 14 21 28 --
+    pinsrw      xmm3, word [block + 35 * SIZEOF_WORD], 7  ;D: w3 = 20 13 06 07 14 21 28 35
+                                                          ;        (Row 3, offset 1)
+    pcmpgtw     xmm4, xmm3                                ;D: w4[i] = (w3[i] < 0 ? -1 : 0);
+    paddw       xmm3, xmm4                                ;D: w3[i] += w4[i];
+    movaps      XMMWORD [t + 24 * SIZEOF_WORD], xmm3      ;D: t[i+24] = w3[i];
+    pxor        xmm4, xmm4                                ;D: w4[i] = 0;
+    pcmpeqw     xmm3, xmm4                                ;D: w3[i] = (w3[i] == 0 ? -1 : 0);
 
-    ; Prepare data
-    xor         ebx, ebx
-    kloop_prepare  0,  1,  8,  16, 9,  2,  3,  10, 17, 24, 32, 25, \
-                   18, 11, 4,  5,  12, 19, 26, 33, 40, 48, 41, 34, \
-                   27, 20, 13, 6,  7,  14, 21, 28, 35, \
-                   xmm0, xmm1, xmm2, xmm3
-    kloop_prepare  32, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, \
-                   30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, \
-                   53, 60, 61, 54, 47, 55, 62, 63, 63, \
-                   xmm4, xmm5, xmm6, xmm7
+    pinsrw      xmm2, word [block + 19 * SIZEOF_WORD], 0  ;C: w2 = 19 26 25 27 48 49 50 51
+    cmp         code, 1 << 31                             ;Z:     Set CF if code < 0x80000000,
+                                                          ;Z:     i.e. if code is positive
+    pinsrw      xmm2, word [block + 33 * SIZEOF_WORD], 2  ;C: w2 = 19 26 33 27 48 49 50 51
+    pinsrw      xmm2, word [block + 40 * SIZEOF_WORD], 3  ;C: w2 = 19 26 33 40 48 49 50 51
+    adc         code, -1                                  ;Z:     code += -1 + (code >= 0 ? 1 : 0);
+    pinsrw      xmm2, word [block + 41 * SIZEOF_WORD], 5  ;C: w2 = 19 26 33 40 48 41 50 51
+    pinsrw      xmm2, word [block + 34 * SIZEOF_WORD], 6  ;C: w2 = 19 26 33 40 48 41 34 51
+    movsxd      codeq, code                               ;Z:     sign extend code
+    pinsrw      xmm2, word [block + 27 * SIZEOF_WORD], 7  ;C: w2 = 19 26 33 40 48 41 34 27
+                                                          ;        (Row 2, offset 1)
+    pcmpgtw     xmm4, xmm2                                ;C: w4[i] = (w2[i] < 0 ? -1 : 0);
+    paddw       xmm2, xmm4                                ;C: w2[i] += w4[i];
+    movaps      XMMWORD [t + 16 * SIZEOF_WORD], xmm2      ;C: t[i+16] = w2[i];
+    pxor        xmm4, xmm4                                ;C: w4[i] = 0;
+    pcmpeqw     xmm2, xmm4                                ;C: w2[i] = (w2[i] == 0 ? -1 : 0);
 
-    pxor        xmm8, xmm8
-    pcmpeqw     xmm0, xmm8              ; tmp0 = _mm_cmpeq_epi16(tmp0, zero);
-    pcmpeqw     xmm1, xmm8              ; tmp1 = _mm_cmpeq_epi16(tmp1, zero);
-    pcmpeqw     xmm2, xmm8              ; tmp2 = _mm_cmpeq_epi16(tmp2, zero);
-    pcmpeqw     xmm3, xmm8              ; tmp3 = _mm_cmpeq_epi16(tmp3, zero);
-    pcmpeqw     xmm4, xmm8              ; tmp4 = _mm_cmpeq_epi16(tmp4, zero);
-    pcmpeqw     xmm5, xmm8              ; tmp5 = _mm_cmpeq_epi16(tmp5, zero);
-    pcmpeqw     xmm6, xmm8              ; tmp6 = _mm_cmpeq_epi16(tmp6, zero);
-    pcmpeqw     xmm7, xmm8              ; tmp7 = _mm_cmpeq_epi16(tmp7, zero);
-    packsswb    xmm0, xmm1              ; tmp0 = _mm_packs_epi16(tmp0, tmp1);
-    packsswb    xmm2, xmm3              ; tmp2 = _mm_packs_epi16(tmp2, tmp3);
-    packsswb    xmm4, xmm5              ; tmp4 = _mm_packs_epi16(tmp4, tmp5);
-    packsswb    xmm6, xmm7              ; tmp6 = _mm_packs_epi16(tmp6, tmp7);
-    pmovmskb    r11d, xmm0              ; index  = ((uint64_t)_mm_movemask_epi8(tmp0)) << 0;
-    pmovmskb    r12d, xmm2              ; index  = ((uint64_t)_mm_movemask_epi8(tmp2)) << 16;
-    pmovmskb    r13d, xmm4              ; index  = ((uint64_t)_mm_movemask_epi8(tmp4)) << 32;
-    pmovmskb    r14d, xmm6              ; index  = ((uint64_t)_mm_movemask_epi8(tmp6)) << 48;
-    shl         r12, 16
-    shl         r14, 16
-    or          r11, r12
-    or          r13, r14
-    shl         r13, 32
-    or          r11, r13
-    not         r11                     ; index = ~index;
+    packsswb    xmm2, xmm3                                ;CD: b2[i] = w2[i], b2[i+8] = w3[i]
+                                                          ;    w/ signed saturation
 
-    ;mov MMWORD [ t1 + DCTSIZE2 * SIZEOF_WORD ], r11
-    ;jmp .EFN
+    movzx       nbitsq, byte [NBITS(codeq)]               ;Z:     nbits = JPEG_NBITS(code);
+    movdqa      xmm3, xmm5                                ;H: w3 = 48 49 50 51 52 53 54 55
+    pmovmskb    tempd, xmm2                               ;Z:     temp = 0;  temp |= ((b2[i] >> 7) << i);
+    pmovmskb    put_bufferd, xmm0                         ;Z:     put_buffer = 0;  put_buffer |= ((b0[i] >> 7) << i);
+    movups      xmm0, XMMWORD [block + 56 * SIZEOF_WORD]  ;H: w0 = 56 57 58 59 60 61 62 63
+    punpckhdq   xmm3, xmm0                                ;H: w3 = 52 53 60 61 54 55 62 63
+    shl         tempd, 16                                 ;Z:     temp <<= 16;
+    psrldq      xmm3, 1 * SIZEOF_WORD                     ;H: w3 = 53 60 61 54 55 62 63 --
+    pxor        xmm2, xmm2                                ;H: w2[i] = 0;
+    or          put_bufferd, tempd                        ;Z:     put_buffer |= temp;
+    pshuflw     xmm3, xmm3, 00111001b                     ;H: w3 = 60 61 54 53 55 62 63 --
+    movq        xmm1, qword [block + 44 * SIZEOF_WORD]    ;G: w1 = 44 45 46 47 -- -- -- --
+    unpcklps    xmm5, xmm0                                ;E: w5 = 48 49 56 57 50 51 58 59
+    pxor        xmm0, xmm0                                ;H: w0[i] = 0;
+    pinsrw      xmm3, word [block + 47 * SIZEOF_WORD], 3  ;H: w3 = 60 61 54 47 55 62 63 --
+                                                          ;        (Row 7, offset 1)
+    pcmpgtw     xmm2, xmm3                                ;H: w2[i] = (w3[i] < 0 ? -1 : 0);
+    paddw       xmm3, xmm2                                ;H: w3[i] += w2[i];
+    movaps      XMMWORD [t + 56 * SIZEOF_WORD], xmm3      ;H: t[i+56] = w3[i];
+    movq        xmm4, qword [block + 36 * SIZEOF_WORD]    ;G: w4 = 36 37 38 39 -- -- -- --
+    pcmpeqw     xmm3, xmm0                                ;H: w3[i] = (w3[i] == 0 ? -1 : 0);
+    punpckldq   xmm4, xmm1                                ;G: w4 = 36 37 44 45 38 39 46 47
+    mov         tempd, [dctbl + c_derived_tbl.ehufco + nbitsq * 4]
+                                                          ;Z:     temp = dctbl->ehufco[nbits];
+    movdqa      xmm1, xmm4                                ;F: w1 = 36 37 44 45 38 39 46 47
+    psrldq      xmm4, 1 * SIZEOF_WORD                     ;G: w4 = 37 44 45 38 39 46 47 --
+    shufpd      xmm1, xmm5, 10b                           ;F: w1 = 36 37 44 45 50 51 58 59
+    and         code, dword [MASK_BITS(nbitsq)]           ;Z:     code &= (1 << nbits) - 1;
+    pshufhw     xmm4, xmm4, 11010011b                     ;G: w4 = 37 44 45 38 -- 39 46 --
+    pslldq      xmm1, 1 * SIZEOF_WORD                     ;F: w1 = -- 36 37 44 45 50 51 58
+    shl         tempq, nbitsb                             ;Z:     temp <<= nbits;
+    pinsrw      xmm4, word [block + 59 * SIZEOF_WORD], 0  ;G: w4 = 59 44 45 38 -- 39 46 --
+    pshufd      xmm1, xmm1, 11011000b                     ;F: w1 = -- 36 45 50 37 44 51 58
+    pinsrw      xmm4, word [block + 52 * SIZEOF_WORD], 1  ;G: w4 = 59 52 45 38 -- 39 46 --
+    or          code, tempd                               ;Z:     code |= temp;
+    movlps      xmm1, qword [block + 20 * SIZEOF_WORD]    ;F: w1 = 20 21 22 23 37 44 51 58
+    pinsrw      xmm4, word [block + 31 * SIZEOF_WORD], 4  ;G: w4 = 59 52 45 38 31 39 46 --
+    pshuflw     xmm1, xmm1, 01110010b                     ;F: w1 = 22 20 23 21 37 44 51 58
+    pinsrw      xmm4, word [block + 53 * SIZEOF_WORD], 7  ;G: w4 = 59 52 45 38 31 39 46 53
+                                                          ;        (Row 6, offset 1)
+    pxor        xmm2, xmm2                                ;G: w2[i] = 0;
+    pcmpgtw     xmm0, xmm4                                ;G: w0[i] = (w4[i] < 0 ? -1 : 0);
+    pinsrw      xmm1, word [block + 15 * SIZEOF_WORD], 1  ;F: w1 = 22 15 23 21 37 44 51 58
+    paddw       xmm4, xmm0                                ;G: w4[i] += w0[i];
+    movaps      XMMWORD [t + 48 * SIZEOF_WORD], xmm4      ;G: t[48+i] = w4[i];
+    pinsrw      xmm1, word [block + 30 * SIZEOF_WORD], 3  ;F: w1 = 22 15 23 30 37 44 51 58
+                                                          ;        (Row 5, offset 1)
+    pcmpeqw     xmm4, xmm2                                ;G: w4[i] = (w4[i] == 0 ? -1 : 0);
+    pinsrw      xmm5, word [block + 42 * SIZEOF_WORD], 0  ;E: w5 = 42 49 56 57 50 51 58 59
 
-    mov         r13d,  INT [r15 + 240 * 4]     ; code_0xf0 = actbl->ehufco[0xf0];
-    movzx       r14d, byte [r15 + 1024 + 240]  ; size_0xf0 = actbl->ehufsi[0xf0];
-    lea         rsi, [t1]
-.BLOOP:
-    bsf         r12, r11                     ; r = __builtin_ctzl(index);
-    jz          .ELOOP
-    mov         rcx, r12
-    lea         rsi, [rsi+r12*2]             ; k += r;
-    shr         r11, cl                      ; index >>= r;
-    movzx       rdi, word [rsi]              ; temp = t1[k];
-    lea         rbx, [rel jpeg_nbits_table]
-    movzx       rdi, byte [rbx + rdi]        ; nbits = JPEG_NBITS(temp);
-.BRLOOP:
-    cmp         r12, 16                 ; while (r > 15) {
-    jl          .ERLOOP
-    EMIT_BITS   r13, r14d               ; EMIT_BITS(code_0xf0, size_0xf0)
-    sub         r12, 16                 ; r -= 16;
-    jmp         .BRLOOP
-.ERLOOP:
-    ; Emit Huffman symbol for run length / number of bits
-    CHECKBUF31  ; uses rcx, rdx
+    packsswb    xmm4, xmm3                                ;GH: b4[i] = w4[i], b4[i+8] = w3[i]
+                                                          ;    w/ signed saturation
 
-    shl         r12, 4                        ; temp3 = (r << 4) + nbits;
-    add         r12, rdi
-    mov         ebx,  INT [r15 + r12 * 4]     ; code = actbl->ehufco[temp3];
-    movzx       ecx, byte [r15 + r12 + 1024]  ; size = actbl->ehufsi[temp3];
-    PUT_BITS    rbx
+    pxor        xmm0, xmm0                                ;F: w0[i] = 0;
+    pinsrw      xmm5, word [block + 43 * SIZEOF_WORD], 5  ;E: w5 = 42 49 56 57 50 43 58 59
+    pcmpgtw     xmm2, xmm1                                ;F: w2[i] = (w1[i] < 0 ? -1 : 0);
+    pmovmskb    tempd, xmm4                               ;Z:     temp = 0;  temp |= ((b4[i] >> 7) << i);
+    pinsrw      xmm5, word [block + 36 * SIZEOF_WORD], 6  ;E: w5 = 42 49 56 57 50 43 36 59
+    paddw       xmm1, xmm2                                ;F: w1[i] += w2[i];
+    movaps      XMMWORD [t + 40 * SIZEOF_WORD], xmm1      ;F: t[40+i] = w1[i];
+    pinsrw      xmm5, word [block + 29 * SIZEOF_WORD], 7  ;E: w5 = 42 49 56 57 50 43 36 29
+                                                          ;        (Row 4, offset 1)
+%undef block
+%define free_bitsq  rdx
+%define free_bitsd  edx
+%define free_bitsb  dl
+    pcmpeqw     xmm1, xmm0                                ;F: w1[i] = (w1[i] == 0 ? -1 : 0);
+    shl         tempq, 48                                 ;Z:     temp <<= 48;
+    pxor        xmm2, xmm2                                ;E: w2[i] = 0;
+    pcmpgtw     xmm0, xmm5                                ;E: w0[i] = (w5[i] < 0 ? -1 : 0);
+    paddw       xmm5, xmm0                                ;E: w5[i] += w0[i];
+    or          tempq, put_buffer                         ;Z:     temp |= put_buffer;
+    movaps      XMMWORD [t + 32 * SIZEOF_WORD], xmm5      ;E: t[32+i] = w5[i];
+    lea         t, [dword t - 2]                          ;Z:     t = &t[-1];
+    pcmpeqw     xmm5, xmm2                                ;E: w5[i] = (w5[i] == 0 ? -1 : 0);
 
-    ;EMIT_CODE(code, size)
+    packsswb    xmm5, xmm1                                ;EF: b5[i] = w5[i], b5[i+8] = w1[i]
+                                                          ;    w/ signed saturation
 
-    movsx       ebx, word [rsi-DCTSIZE2*2]    ; temp2 = t2[k];
-    ; Mask off any extra bits in code
-    mov         rcx, rdi
-    mov         rdx, 1
-    shl         rdx, cl
-    dec         rdx
-    and         rbx, rdx                ; temp2 &= (((JLONG)1)<<nbits) - 1;
-    PUT_BITS    rbx                     ; PUT_BITS(temp2, nbits)
+    add         nbitsb, byte [dctbl + c_derived_tbl.ehufsi + nbitsq]
+                                                          ;Z:     nbits += dctbl->ehufsi[nbits];
+%undef dctbl
+%define code_temp  r8d
+    pmovmskb    indexd, xmm5                              ;Z:     index = 0;  index |= ((b5[i] >> 7) << i);
+    mov         free_bitsd, [state+working_state.cur.free_bits]
+                                                          ;Z:     free_bits = state->cur.free_bits;
+    pcmpeqw     xmm1, xmm1                                ;Z:     b1[i] = 0xFF;
+    shl         index, 32                                 ;Z:     index <<= 32;
+    mov         put_buffer, [state+working_state.cur.put_buffer.simd]
+                                                          ;Z:     put_buffer = state->cur.put_buffer.simd;
+    or          index, tempq                              ;Z:     index |= temp;
+    not         index                                     ;Z:     index = ~index;
+    sub         free_bitsb, nbitsb                        ;Z:     if ((free_bits -= nbits) >= 0)
+    jnl         .ENTRY_SKIP_EMIT_CODE                     ;Z:       goto .ENTRY_SKIP_EMIT_CODE;
+    align       16
+.EMIT_CODE:                                               ;Z:     .EMIT_CODE:
+    EMIT_QWORD  .BLOOP_COND                               ;Z:     insert code, flush buffer, goto .BLOOP_COND
 
-    shr         r11, 1                  ; index >>= 1;
-    add         rsi, 2                  ; ++k;
-    jmp         .BLOOP
-.ELOOP:
-    ; If the last coef(s) were zero, emit an end-of-block code
-    lea         rdi, [t1 + (DCTSIZE2-1) * 2]  ; r = DCTSIZE2-1-k;
-    cmp         rdi, rsi                      ; if (r > 0) {
-    je          .EFN
-    mov         ebx,  INT [r15]               ; code = actbl->ehufco[0];
-    movzx       r12d, byte [r15 + 1024]       ; size = actbl->ehufsi[0];
-    EMIT_BITS   rbx, r12d
-.EFN:
-    pop         r10
-    ; Save put_buffer & put_bits
-    mov         MMWORD [r10+16], put_buffer  ; state->cur.put_buffer = put_buffer;
-    mov         DWORD  [r10+24], put_bits    ; state->cur.put_bits = put_bits;
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    pop         rbx
-    uncollect_args 6
-    pop_xmm     4
-    mov         rsp, rbp                ; rsp <- aligned rbp
-    pop         rsp                     ; rsp <- original rbp
+    align       16
+.BRLOOP:                                                  ; do {
+    lea         code_temp, [nbitsq - 16]                  ;   code_temp = nbits - 16;
+    movzx       nbits, byte [actbl + c_derived_tbl.ehufsi + 0xf0]
+                                                          ;   nbits = actbl->ehufsi[0xf0];
+    mov         code, [actbl + c_derived_tbl.ehufco + 0xf0 * 4]
+                                                          ;   code = actbl->ehufco[0xf0];
+    sub         free_bitsb, nbitsb                        ;   if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_BRLOOP_CODE                         ;     goto .EMIT_BRLOOP_CODE;
+    shl         put_buffer, nbitsb                        ;   put_buffer <<= nbits;
+    mov         nbits, code_temp                          ;   nbits = code_temp;
+    or          put_buffer, codeq                         ;   put_buffer |= code;
+    cmp         nbits, 16                                 ;   if (nbits <= 16)
+    jle         .ERLOOP                                   ;     break;
+    jmp         .BRLOOP                                   ; } while (1);
+
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+    times 5     nop
+.ENTRY_SKIP_EMIT_CODE:                                    ; .ENTRY_SKIP_EMIT_CODE:
+    shl         put_buffer, nbitsb                        ; put_buffer <<= nbits;
+    or          put_buffer, codeq                         ; put_buffer |= code;
+.BLOOP_COND:                                              ; .BLOOP_COND:
+    test        index, index                              ; if (index != 0)
+    jz          .ELOOP                                    ; {
+.BLOOP:                                                   ;   do {
+    xor         nbits, nbits                              ;     nbits = 0;  /* kill tzcnt input dependency */
+    tzcnt       nbitsq, index                             ;     nbits = # of trailing 0 bits in index
+    inc         nbits                                     ;     ++nbits;
+    lea         t, [t + nbitsq * 2]                       ;     t = &t[nbits];
+    shr         index, nbitsb                             ;     index >>= nbits;
+.EMIT_BRLOOP_CODE_END:                                    ; .EMIT_BRLOOP_CODE_END:
+    cmp         nbits, 16                                 ;     if (nbits > 16)
+    jg          .BRLOOP                                   ;       goto .BRLOOP;
+.ERLOOP:                                                  ; .ERLOOP:
+    movsx       codeq, word [t]                           ;     code = *t;
+    lea         tempd, [nbitsq * 2]                       ;     temp = nbits * 2;
+    movzx       nbits, byte [NBITS(codeq)]                ;     nbits = JPEG_NBITS(code);
+    lea         tempd, [nbitsq + tempq * 8]               ;     temp = temp * 8 + nbits;
+    mov         code_temp, [actbl + c_derived_tbl.ehufco + (tempq - 16) * 4]
+                                                          ;     code_temp = actbl->ehufco[temp-16];
+    shl         code_temp, nbitsb                         ;     code_temp <<= nbits;
+    and         code, dword [MASK_BITS(nbitsq)]           ;     code &= (1 << nbits) - 1;
+    add         nbitsb, [actbl + c_derived_tbl.ehufsi + (tempq - 16)]
+                                                          ;     free_bits -= actbl->ehufsi[temp-16];
+    or          code, code_temp                           ;     code |= code_temp;
+    sub         free_bitsb, nbitsb                        ;     if ((free_bits -= nbits) <= 0)
+    jle         .EMIT_CODE                                ;       goto .EMIT_CODE;
+    shl         put_buffer, nbitsb                        ;     put_buffer <<= nbits;
+    or          put_buffer, codeq                         ;     put_buffer |= code;
+    test        index, index
+    jnz         .BLOOP                                    ;   } while (index != 0);
+.ELOOP:                                                   ; }  /* index != 0 */
+    sub         td, esp                                   ; t -= (WIN64: &t_[0], UNIX: &t_[64]);
+%ifdef WIN64
+    cmp         td, (DCTSIZE2 - 2) * SIZEOF_WORD          ; if (t != 62)
+%else
+    cmp         td, -2 * SIZEOF_WORD                      ; if (t != -2)
+%endif
+    je          .EFN                                      ; {
+    movzx       nbits, byte [actbl + c_derived_tbl.ehufsi + 0]
+                                                          ;   nbits = actbl->ehufsi[0];
+    mov         code, [actbl + c_derived_tbl.ehufco + 0]  ;   code = actbl->ehufco[0];
+    sub         free_bitsb, nbitsb                        ;   if ((free_bits -= nbits) <= 0)
+    jg          .EFN_SKIP_EMIT_CODE                       ;   {
+    EMIT_QWORD  .EFN                                      ;     insert code, flush buffer
+    align       16
+.EFN_SKIP_EMIT_CODE:                                      ;   } else {
+    shl         put_buffer, nbitsb                        ;     put_buffer <<= nbits;
+    or          put_buffer, codeq                         ;     put_buffer |= code;
+.EFN:                                                     ; } }
+    mov         [state + working_state.cur.put_buffer.simd], put_buffer
+                                                          ; state->cur.put_buffer.simd = put_buffer;
+    mov         byte [state + working_state.cur.free_bits], free_bitsb
+                                                          ; state->cur.free_bits = free_bits;
+%ifdef WIN64
+    sub         rsp, -DCTSIZE2 * SIZEOF_WORD
+    pop         r12
+    pop         rdi
+    pop         rsi
     pop         rbp
+    pop         rbx
+%else
+    pop         r12
+    pop         rbp
+    pop         rbx
+%endif
     ret
 
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    align       16
+.EMIT_BRLOOP_CODE:
+    EMIT_QWORD  .EMIT_BRLOOP_CODE_END, { mov nbits, code_temp }
+                                                          ; insert code, flush buffer,
+                                                          ; nbits = code_temp, goto .EMIT_BRLOOP_CODE_END
+
 ; For some reason, the OS X linker does not honor the request to align the
 ; segment unless we do this.
     align       32
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcphuff-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcphuff-sse2.asm
index b17488a..01b5c02 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcphuff-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcphuff-sse2.asm
@@ -16,8 +16,6 @@
 ;
 ; This file contains an SSE2 implementation of data preparation for progressive
 ; Huffman encoding.  See jcphuff.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -322,6 +320,8 @@
     add         LUT, 16*SIZEOF_INT
     dec         K
     jnz         .BLOOP16
+    test        LEN, 15
+    je          .PADDING
 .ELOOP16:
     test        LEN, 8
     jz          .TRY7
@@ -504,6 +504,8 @@
     add         KK, 16
     dec         K
     jnz         .BLOOPR16
+    test        LEN, 15
+    je          .PADDINGR
 .ELOOPR16:
     test        LEN, 8
     jz          .TRYR7
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-avx2.asm
index 9d5a861..b32527a 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-avx2.asm
@@ -4,6 +4,7 @@
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,8 +15,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -73,7 +72,7 @@
     push        rax
     push        rcx
 
-    mov         rdi, JSAMPROW [rsi]
+    mov         rdip, JSAMPROW [rsi]
     add         rdi, rdx
     mov         al, JSAMPLE [rdi-1]
 
@@ -109,8 +108,8 @@
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 
     cmp         rcx, byte SIZEOF_YMMWORD
     jae         short .columnloop
@@ -235,7 +234,7 @@
     push        rax
     push        rcx
 
-    mov         rdi, JSAMPROW [rsi]
+    mov         rdip, JSAMPROW [rsi]
     add         rdi, rdx
     mov         al, JSAMPLE [rdi-1]
 
@@ -271,9 +270,9 @@
     push        rdi
     push        rsi
 
-    mov         rdx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1
-    mov         rdi, JSAMPROW [rdi]                    ; outptr
+    mov         rdxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rsip, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1
+    mov         rdip, JSAMPROW [rdi]                    ; outptr
 
     cmp         rcx, byte SIZEOF_YMMWORD
     jae         short .columnloop
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-sse2.asm
index 1b31536..2fcfe45 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jcsample-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -72,7 +71,7 @@
     push        rax
     push        rcx
 
-    mov         rdi, JSAMPROW [rsi]
+    mov         rdip, JSAMPROW [rsi]
     add         rdi, rdx
     mov         al, JSAMPLE [rdi-1]
 
@@ -107,8 +106,8 @@
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 
     cmp         rcx, byte SIZEOF_XMMWORD
     jae         short .columnloop
@@ -217,7 +216,7 @@
     push        rax
     push        rcx
 
-    mov         rdi, JSAMPROW [rsi]
+    mov         rdip, JSAMPROW [rsi]
     add         rdi, rdx
     mov         al, JSAMPLE [rdi-1]
 
@@ -252,9 +251,9 @@
     push        rdi
     push        rsi
 
-    mov         rdx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1
-    mov         rdi, JSAMPROW [rdi]                    ; outptr
+    mov         rdxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rsip, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1
+    mov         rdip, JSAMPROW [rdi]                    ; outptr
 
     cmp         rcx, byte SIZEOF_XMMWORD
     jae         short .columnloop
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-avx2.asm
index e2b96c7..2370fda 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-avx2.asm
@@ -4,6 +4,7 @@
 ; Copyright 2009, 2012 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2012, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,8 +15,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -60,9 +59,9 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     lea         rsi, [rsi+rcx*SIZEOF_JSAMPROW]
     lea         rbx, [rbx+rcx*SIZEOF_JSAMPROW]
     lea         rdx, [rdx+rcx*SIZEOF_JSAMPROW]
@@ -81,10 +80,10 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr0
-    mov         rbx, JSAMPROW [rbx]     ; inptr1
-    mov         rdx, JSAMPROW [rdx]     ; inptr2
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr0
+    mov         rbxp, JSAMPROW [rbx]    ; inptr1
+    mov         rdxp, JSAMPROW [rdx]    ; inptr2
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 .columnloop:
 
     vmovdqu     ymm5, YMMWORD [rbx]     ; ymm5=Cb(0123456789ABCDEFGHIJKLMNOPQRSTUV)
@@ -334,7 +333,7 @@
     vmovd       eax, xmmA
     cmp         rcx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [rdi], ax
+    mov         word [rdi], ax
     add         rdi, byte SIZEOF_WORD
     sub         rcx, byte SIZEOF_WORD
     shr         rax, 16
@@ -343,7 +342,7 @@
     ; space.
     test        rcx, rcx
     jz          short .nextrow
-    mov         BYTE [rdi], al
+    mov         byte [rdi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-sse2.asm
index a94954b..e07c8d7 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolext-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009, 2012 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2012, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -59,9 +58,9 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     lea         rsi, [rsi+rcx*SIZEOF_JSAMPROW]
     lea         rbx, [rbx+rcx*SIZEOF_JSAMPROW]
     lea         rdx, [rdx+rcx*SIZEOF_JSAMPROW]
@@ -80,10 +79,10 @@
     push        rsi
     push        rcx                     ; col
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr0
-    mov         rbx, JSAMPROW [rbx]     ; inptr1
-    mov         rdx, JSAMPROW [rdx]     ; inptr2
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr0
+    mov         rbxp, JSAMPROW [rbx]    ; inptr1
+    mov         rdxp, JSAMPROW [rdx]    ; inptr2
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 .columnloop:
 
     movdqa      xmm5, XMMWORD [rbx]     ; xmm5=Cb(0123456789ABCDEF)
@@ -306,7 +305,7 @@
     movd        eax, xmmA
     cmp         rcx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [rdi], ax
+    mov         word [rdi], ax
     add         rdi, byte SIZEOF_WORD
     sub         rcx, byte SIZEOF_WORD
     shr         rax, 16
@@ -315,7 +314,7 @@
     ; space.
     test        rcx, rcx
     jz          short .nextrow
-    mov         BYTE [rdi], al
+    mov         byte [rdi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-avx2.asm
index abad176..43de9db 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-sse2.asm
index e7079f6..b3f1fec 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdcolor-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-avx2.asm
index ca3f063..9515a17 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-avx2.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-sse2.asm
index f3e09fa..aedccc2 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdmerge-sse2.asm
@@ -13,8 +13,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-avx2.asm
index 04e8a94..8b264b4 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-avx2.asm
@@ -4,6 +4,7 @@
 ; Copyright 2009, 2012 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2012, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,8 +15,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -60,14 +59,14 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     mov         rdi, r13
-    mov         rsi, JSAMPROW [rsi+rcx*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rbx, JSAMPROW [rbx+rcx*SIZEOF_JSAMPROW]  ; inptr1
-    mov         rdx, JSAMPROW [rdx+rcx*SIZEOF_JSAMPROW]  ; inptr2
-    mov         rdi, JSAMPROW [rdi]                      ; outptr
+    mov         rsip, JSAMPROW [rsi+rcx*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rbxp, JSAMPROW [rbx+rcx*SIZEOF_JSAMPROW]  ; inptr1
+    mov         rdxp, JSAMPROW [rdx+rcx*SIZEOF_JSAMPROW]  ; inptr2
+    mov         rdip, JSAMPROW [rdi]                      ; outptr
 
     pop         rcx                     ; col
 
@@ -339,7 +338,7 @@
     vmovd       eax, xmmA
     cmp         rcx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [rdi], ax
+    mov         word [rdi], ax
     add         rdi, byte SIZEOF_WORD
     sub         rcx, byte SIZEOF_WORD
     shr         rax, 16
@@ -348,7 +347,7 @@
     ; space.
     test        rcx, rcx
     jz          short .endcolumn
-    mov         BYTE [rdi], al
+    mov         byte [rdi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
@@ -516,15 +515,16 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     mov         rdi, r13
     lea         rsi, [rsi+rcx*SIZEOF_JSAMPROW]
 
-    push        rdx                     ; inptr2
-    push        rbx                     ; inptr1
-    push        rsi                     ; inptr00
+    sub         rsp, SIZEOF_JSAMPARRAY*4
+    mov         JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY], rsip  ; intpr00
+    mov         JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY], rbxp  ; intpr1
+    mov         JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY], rdxp  ; intpr2
     mov         rbx, rsp
 
     push        rdi
@@ -548,16 +548,16 @@
     pop         rax
     pop         rcx
     pop         rdi
-    pop         rsi
-    pop         rbx
-    pop         rdx
+    mov         rsip, JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY]
 
     add         rdi, byte SIZEOF_JSAMPROW  ; outptr1
     add         rsi, byte SIZEOF_JSAMPROW  ; inptr01
 
-    push        rdx                     ; inptr2
-    push        rbx                     ; inptr1
-    push        rsi                     ; inptr00
+    mov         JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY], rsip  ; intpr00
+    mov         JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY], rbxp  ; intpr1
+    mov         JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY], rdxp  ; intpr2
     mov         rbx, rsp
 
     push        rdi
@@ -581,9 +581,10 @@
     pop         rax
     pop         rcx
     pop         rdi
-    pop         rsi
-    pop         rbx
-    pop         rdx
+    mov         rsip, JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY]
+    add         rsp, SIZEOF_JSAMPARRAY*4
 
     pop         rbx
     uncollect_args 4
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-sse2.asm
index 1cc3345..eb3ab9d 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdmrgext-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009, 2012 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2012, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jcolsamp.inc"
 
@@ -59,14 +58,14 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     mov         rdi, r13
-    mov         rsi, JSAMPROW [rsi+rcx*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rbx, JSAMPROW [rbx+rcx*SIZEOF_JSAMPROW]  ; inptr1
-    mov         rdx, JSAMPROW [rdx+rcx*SIZEOF_JSAMPROW]  ; inptr2
-    mov         rdi, JSAMPROW [rdi]                      ; outptr
+    mov         rsip, JSAMPROW [rsi+rcx*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rbxp, JSAMPROW [rbx+rcx*SIZEOF_JSAMPROW]  ; inptr1
+    mov         rdxp, JSAMPROW [rdx+rcx*SIZEOF_JSAMPROW]  ; inptr2
+    mov         rdip, JSAMPROW [rdi]                      ; outptr
 
     pop         rcx                     ; col
 
@@ -310,7 +309,7 @@
     movd        eax, xmmA
     cmp         rcx, byte SIZEOF_WORD
     jb          short .column_st1
-    mov         WORD [rdi], ax
+    mov         word [rdi], ax
     add         rdi, byte SIZEOF_WORD
     sub         rcx, byte SIZEOF_WORD
     shr         rax, 16
@@ -319,7 +318,7 @@
     ; space.
     test        rcx, rcx
     jz          short .endcolumn
-    mov         BYTE [rdi], al
+    mov         byte [rdi], al
 
 %else  ; RGB_PIXELSIZE == 4 ; -----------
 
@@ -458,15 +457,16 @@
 
     mov         rdi, r11
     mov         ecx, r12d
-    mov         rsi, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
-    mov         rbx, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
-    mov         rdx, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
+    mov         rsip, JSAMPARRAY [rdi+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rdi+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rdi+2*SIZEOF_JSAMPARRAY]
     mov         rdi, r13
     lea         rsi, [rsi+rcx*SIZEOF_JSAMPROW]
 
-    push        rdx                     ; inptr2
-    push        rbx                     ; inptr1
-    push        rsi                     ; inptr00
+    sub         rsp, SIZEOF_JSAMPARRAY*4
+    mov         JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY], rsip  ; intpr00
+    mov         JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY], rbxp  ; intpr1
+    mov         JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY], rdxp  ; intpr2
     mov         rbx, rsp
 
     push        rdi
@@ -490,16 +490,16 @@
     pop         rax
     pop         rcx
     pop         rdi
-    pop         rsi
-    pop         rbx
-    pop         rdx
+    mov         rsip, JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY]
 
     add         rdi, byte SIZEOF_JSAMPROW  ; outptr1
     add         rsi, byte SIZEOF_JSAMPROW  ; inptr01
 
-    push        rdx                     ; inptr2
-    push        rbx                     ; inptr1
-    push        rsi                     ; inptr00
+    mov         JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY], rsip  ; intpr00
+    mov         JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY], rbxp  ; intpr1
+    mov         JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY], rdxp  ; intpr2
     mov         rbx, rsp
 
     push        rdi
@@ -523,9 +523,10 @@
     pop         rax
     pop         rcx
     pop         rdi
-    pop         rsi
-    pop         rbx
-    pop         rdx
+    mov         rsip, JSAMPARRAY [rsp+0*SIZEOF_JSAMPARRAY]
+    mov         rbxp, JSAMPARRAY [rsp+1*SIZEOF_JSAMPARRAY]
+    mov         rdxp, JSAMPARRAY [rsp+2*SIZEOF_JSAMPARRAY]
+    add         rsp, SIZEOF_JSAMPARRAY*4
 
     pop         rbx
     uncollect_args 4
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-avx2.asm
index 10fa5c4..1e4979f 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-avx2.asm
@@ -4,6 +4,7 @@
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
 ; Copyright (C) 2015, Intel Corporation.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,8 +15,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -78,7 +77,7 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 
     vpxor       ymm0, ymm0, ymm0                 ; ymm0=(all 0's)
     vpcmpeqb    xmm9, xmm9, xmm9
@@ -92,8 +91,8 @@
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 
     test        rax, SIZEOF_YMMWORD-1
     jz          short .skip
@@ -237,18 +236,18 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rax                     ; colctr
     push        rcx
     push        rdi
     push        rsi
 
-    mov         rcx, JSAMPROW [rsi-1*SIZEOF_JSAMPROW]  ; inptr1(above)
-    mov         rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1(below)
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
-    mov         rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
+    mov         rcxp, JSAMPROW [rsi-1*SIZEOF_JSAMPROW]  ; inptr1(above)
+    mov         rbxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rsip, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1(below)
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
+    mov         rdip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
 
     vpxor       ymm8, ymm8, ymm8                 ; ymm8=(all 0's)
     vpcmpeqb    xmm9, xmm9, xmm9
@@ -541,13 +540,13 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
     mov         rax, rdx                ; colctr
 .columnloop:
 
@@ -631,14 +630,14 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]                    ; inptr
-    mov         rbx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
-    mov         rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
+    mov         rsip, JSAMPROW [rsi]                   ; inptr
+    mov         rbxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW] ; outptr0
+    mov         rdip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW] ; outptr1
     mov         rax, rdx                               ; colctr
 .columnloop:
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-sse2.asm
index d8ccda9..38dbcee 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jdsample-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -76,14 +75,14 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rax                     ; colctr
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
 
     test        rax, SIZEOF_XMMWORD-1
     jz          short .skip
@@ -223,18 +222,18 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rax                     ; colctr
     push        rcx
     push        rdi
     push        rsi
 
-    mov         rcx, JSAMPROW [rsi-1*SIZEOF_JSAMPROW]  ; inptr1(above)
-    mov         rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
-    mov         rsi, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1(below)
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
-    mov         rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
+    mov         rcxp, JSAMPROW [rsi-1*SIZEOF_JSAMPROW]  ; inptr1(above)
+    mov         rbxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; inptr0
+    mov         rsip, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; inptr1(below)
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
+    mov         rdip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
 
     test        rax, SIZEOF_XMMWORD-1
     jz          short .skip
@@ -514,13 +513,13 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]     ; inptr
-    mov         rdi, JSAMPROW [rdi]     ; outptr
+    mov         rsip, JSAMPROW [rsi]    ; inptr
+    mov         rdip, JSAMPROW [rdi]    ; outptr
     mov         rax, rdx                ; colctr
 .columnloop:
 
@@ -602,14 +601,14 @@
 
     mov         rsi, r12                ; input_data
     mov         rdi, r13
-    mov         rdi, JSAMPARRAY [rdi]   ; output_data
+    mov         rdip, JSAMPARRAY [rdi]  ; output_data
 .rowloop:
     push        rdi
     push        rsi
 
-    mov         rsi, JSAMPROW [rsi]                    ; inptr
-    mov         rbx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]  ; outptr0
-    mov         rdi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]  ; outptr1
+    mov         rsip, JSAMPROW [rsi]                   ; inptr
+    mov         rbxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW] ; outptr0
+    mov         rdip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW] ; outptr1
     mov         rax, rdx                               ; colctr
 .columnloop:
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctflt-sse.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctflt-sse.asm
index 26f9fb6..ef27966 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctflt-sse.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctflt-sse.asm
@@ -17,8 +17,6 @@
 ; This file contains a floating-point implementation of the forward DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jfdctflt.c; see the jfdctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctfst-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctfst-sse2.asm
index aaf8b9e..2e1bfe6 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctfst-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctfst-sse2.asm
@@ -18,8 +18,6 @@
 ; the forward DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jfdctfst.c; see the jfdctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-avx2.asm
index 448f47d..e56258b 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-avx2.asm
@@ -2,7 +2,7 @@
 ; jfdctint.asm - accurate integer FDCT (64-bit AVX2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, 2018, D. R. Commander.
+; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; forward DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -105,7 +103,7 @@
 %endmacro
 
 ; --------------------------------------------------------------------------
-; In-place 8x8x16-bit slow integer forward DCT using AVX2 instructions
+; In-place 8x8x16-bit accurate integer forward DCT using AVX2 instructions
 ; %1-%4: Input/output registers
 ; %5-%8: Temp registers
 ; %9:    Pass (1 or 2)
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-sse2.asm
index ef16a52..ec1f383 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jfdctint-sse2.asm
@@ -2,7 +2,7 @@
 ; jfdctint.asm - accurate integer FDCT (64-bit SSE2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2009, 2016, 2020, D. R. Commander.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +14,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; forward DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jidctflt-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jidctflt-sse2.asm
index b676ef3..60bf961 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jidctflt-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jidctflt-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -17,8 +18,6 @@
 ; This file contains a floating-point implementation of the inverse DCT
 ; (Discrete Cosine Transform). The following code is based directly on
 ; the IJG's original jidctflt.c; see the jidctflt.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -95,8 +94,8 @@
     mov         rcx, DCTSIZE/4          ; ctr
 .columnloop:
 %ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE
-    mov         eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movq        xmm1, XMM_MMWORD [MMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
@@ -457,12 +456,12 @@
     pshufd      xmm5, xmm6, 0x4E  ; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07)
     pshufd      xmm3, xmm7, 0x4E  ; xmm3=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27)
 
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
-    mov         rbx, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
+    mov         rbxp, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
     movq        XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE], xmm7
-    mov         rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
-    mov         rbx, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
+    mov         rbxp, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm5
     movq        XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE], xmm3
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jidctfst-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jidctfst-sse2.asm
index c6c42f9..cb97fdf 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jidctfst-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jidctfst-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -18,8 +19,6 @@
 ; the inverse DCT (Discrete Cosine Transform). The following code is
 ; based directly on the IJG's original jidctfst.c; see the jidctfst.c
 ; for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -111,8 +110,8 @@
     mov         rsi, r11                ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_IFAST_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
@@ -462,21 +461,21 @@
     pshufd      xmm6, xmm4, 0x4E  ; xmm6=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
     pshufd      xmm2, xmm7, 0x4E  ; xmm2=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
 
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
-    mov         rdx, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm7
 
-    mov         rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm5
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm0
-    mov         rdx, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-avx2.asm
index b60b44f..ca7e317 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-avx2.asm
@@ -2,7 +2,8 @@
 ; jidctint.asm - accurate integer IDCT (64-bit AVX2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, 2018, D. R. Commander.
+; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +15,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; inverse DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jidctint.c; see the jidctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -115,7 +114,7 @@
 %endmacro
 
 ; --------------------------------------------------------------------------
-; In-place 8x8x16-bit slow integer inverse DCT using AVX2 instructions
+; In-place 8x8x16-bit accurate integer inverse DCT using AVX2 instructions
 ; %1-%4:  Input/output registers
 ; %5-%12: Temp registers
 ; %9:     Pass (1 or 2)
@@ -292,8 +291,8 @@
     ; ---- Pass 1: process columns.
 
 %ifndef NO_ZERO_COLUMN_TEST_ISLOW_AVX2
-    mov         eax, DWORD [DWBLOCK(1,0,r11,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,r11,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,r11,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,r11,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,r11,SIZEOF_JCOEF)]
@@ -389,23 +388,23 @@
 
     mov         eax, r13d
 
-    mov         rdx, JSAMPROW [r12+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rsi, JSAMPROW [r12+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [r12+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r12+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm0
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm1
 
-    mov         rdx, JSAMPROW [r12+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rsi, JSAMPROW [r12+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [r12+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r12+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm2
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
 
-    mov         rdx, JSAMPROW [r12+4*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rsi, JSAMPROW [r12+5*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [r12+4*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r12+5*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm5
 
-    mov         rdx, JSAMPROW [r12+6*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rsi, JSAMPROW [r12+7*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [r12+6*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r12+7*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm7
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-sse2.asm
index 83fc344..7aa869b 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jidctint-sse2.asm
@@ -2,7 +2,8 @@
 ; jidctint.asm - accurate integer IDCT (64-bit SSE2)
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
-; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2009, 2016, 2020, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,12 +15,10 @@
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
 ;
-; This file contains a slow-but-accurate integer implementation of the
+; This file contains a slower but more accurate integer implementation of the
 ; inverse DCT (Discrete Cosine Transform). The following code is based
 ; directly on the IJG's original jidctint.c; see the jidctint.c for
 ; more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -124,8 +123,8 @@
     mov         rsi, r11                ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_ISLOW_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
     jnz         near .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
@@ -819,21 +818,21 @@
     pshufd      xmm2, xmm4, 0x4E  ; xmm2=(50 51 52 53 54 55 56 57 40 41 42 43 44 45 46 47)
     pshufd      xmm5, xmm3, 0x4E  ; xmm5=(70 71 72 73 74 75 76 77 60 61 62 63 64 65 66 67)
 
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm7
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm1
-    mov         rdx, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+4*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+6*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
 
-    mov         rdx, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm0
-    mov         rdx, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+5*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+7*SIZEOF_JSAMPROW]
     movq        XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm2
     movq        XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm5
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jidctred-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jidctred-sse2.asm
index af64fdc..4ece9d8 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jidctred-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jidctred-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -18,8 +19,6 @@
 ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block.
 ; The following code is based directly on the IJG's original jidctred.c;
 ; see the jidctred.c for more details.
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -132,8 +131,8 @@
     mov         rsi, r11                ; inptr
 
 %ifndef NO_ZERO_COLUMN_TEST_4X4_SSE2
-    mov         eax, DWORD [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
-    or          eax, DWORD [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
+    mov         eax, dword [DWBLOCK(1,0,rsi,SIZEOF_JCOEF)]
+    or          eax, dword [DWBLOCK(2,0,rsi,SIZEOF_JCOEF)]
     jnz         short .columnDCT
 
     movdqa      xmm0, XMMWORD [XMMBLOCK(1,0,rsi,SIZEOF_JCOEF)]
@@ -381,12 +380,12 @@
     pshufd      xmm1, xmm4, 0x4E        ; xmm1=(20 21 22 23 30 31 32 33 00 ..)
     pshufd      xmm3, xmm4, 0x93        ; xmm3=(30 31 32 33 00 01 02 03 10 ..)
 
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
     movd        XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm4
     movd        XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2
-    mov         rdx, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
+    mov         rdxp, JSAMPROW [rdi+2*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+3*SIZEOF_JSAMPROW]
     movd        XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1
     movd        XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3
 
@@ -560,10 +559,10 @@
     pextrw      ebx, xmm6, 0x00         ; ebx=(C0 D0 -- --)
     pextrw      ecx, xmm6, 0x01         ; ecx=(C1 D1 -- --)
 
-    mov         rdx, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
-    mov         rsi, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
-    mov         WORD [rdx+rax*SIZEOF_JSAMPLE], bx
-    mov         WORD [rsi+rax*SIZEOF_JSAMPLE], cx
+    mov         rdxp, JSAMPROW [rdi+0*SIZEOF_JSAMPROW]
+    mov         rsip, JSAMPROW [rdi+1*SIZEOF_JSAMPROW]
+    mov         word [rdx+rax*SIZEOF_JSAMPLE], bx
+    mov         word [rsi+rax*SIZEOF_JSAMPLE], cx
 
     pop         rbx
     uncollect_args 4
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jquantf-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jquantf-sse2.asm
index 4600eec..ab2e395 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jquantf-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jquantf-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -53,8 +52,8 @@
     mov         rdi, r12
     mov         rcx, DCTSIZE/2
 .convloop:
-    mov         rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdx, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rbxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
 
     movq        xmm0, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]
     movq        xmm1, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-avx2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-avx2.asm
index b7243e4..70fe811 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-avx2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-avx2.asm
@@ -4,6 +4,7 @@
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, 2018, D. R. Commander.
 ; Copyright (C) 2016, Matthieu Darbois.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -14,8 +15,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -46,23 +45,23 @@
 
     mov         eax, r11d
 
-    mov         rsi, JSAMPROW [r10+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdi, JSAMPROW [r10+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r10+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdip, JSAMPROW [r10+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        xmm0, XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE]
     pinsrq      xmm0, XMM_MMWORD [rdi+rax*SIZEOF_JSAMPLE], 1
 
-    mov         rsi, JSAMPROW [r10+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdi, JSAMPROW [r10+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r10+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdip, JSAMPROW [r10+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        xmm1, XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE]
     pinsrq      xmm1, XMM_MMWORD [rdi+rax*SIZEOF_JSAMPLE], 1
 
-    mov         rsi, JSAMPROW [r10+4*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdi, JSAMPROW [r10+5*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r10+4*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdip, JSAMPROW [r10+5*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        xmm2, XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE]
     pinsrq      xmm2, XMM_MMWORD [rdi+rax*SIZEOF_JSAMPLE], 1
 
-    mov         rsi, JSAMPROW [r10+6*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdi, JSAMPROW [r10+7*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rsip, JSAMPROW [r10+6*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdip, JSAMPROW [r10+7*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
     movq        xmm3, XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE]
     pinsrq      xmm3, XMM_MMWORD [rdi+rax*SIZEOF_JSAMPLE], 1
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-sse2.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-sse2.asm
index 7ff7275..3ee4420 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-sse2.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jquanti-sse2.asm
@@ -3,6 +3,7 @@
 ;
 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
 ; Copyright (C) 2009, 2016, D. R. Commander.
+; Copyright (C) 2018, Matthias Räncker.
 ;
 ; Based on the x86 SIMD extension for IJG JPEG library
 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
@@ -13,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 %include "jdct.inc"
@@ -53,14 +52,14 @@
     mov         rdi, r12
     mov         rcx, DCTSIZE/4
 .convloop:
-    mov         rbx, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdx, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rbxp, JSAMPROW [rsi+0*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [rsi+1*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
 
     movq        xmm0, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]  ; xmm0=(01234567)
     movq        xmm1, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]  ; xmm1=(89ABCDEF)
 
-    mov         rbx, JSAMPROW [rsi+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
-    mov         rdx, JSAMPROW [rsi+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rbxp, JSAMPROW [rsi+2*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
+    mov         rdxp, JSAMPROW [rsi+3*SIZEOF_JSAMPROW]  ; (JSAMPLE *)
 
     movq        xmm2, XMM_MMWORD [rbx+rax*SIZEOF_JSAMPLE]  ; xmm2=(GHIJKLMN)
     movq        xmm3, XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE]  ; xmm3=(OPQRSTUV)
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jsimd.c b/src/third_party/libjpeg-turbo/simd/x86_64/jsimd.c
index 070d80f..eb76679 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jsimd.c
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jsimd.c
@@ -23,8 +23,6 @@
 #include "../jsimd.h"
 #include "jconfigint.h"
 
-#include <stdlib.h>
-
 /*
  * In the PIC cases, we have no guarantee that constants will keep
  * their alignment. This macro allows us to verify it at runtime.
@@ -1033,8 +1031,6 @@
     return 0;
   if (sizeof(JCOEF) != 2)
     return 0;
-  if (SIZEOF_SIZE_T != 8)
-    return 0;
   if (simd_support & JSIMD_SSE2)
     return 1;
 
@@ -1059,8 +1055,6 @@
     return 0;
   if (sizeof(JCOEF) != 2)
     return 0;
-  if (SIZEOF_SIZE_T != 8)
-    return 0;
   if (simd_support & JSIMD_SSE2)
     return 1;
 
diff --git a/src/third_party/libjpeg-turbo/simd/x86_64/jsimdcpu.asm b/src/third_party/libjpeg-turbo/simd/x86_64/jsimdcpu.asm
index 42979be..705f813 100644
--- a/src/third_party/libjpeg-turbo/simd/x86_64/jsimdcpu.asm
+++ b/src/third_party/libjpeg-turbo/simd/x86_64/jsimdcpu.asm
@@ -14,8 +14,6 @@
 ; assembler (including Borland's Turbo Assembler).
 ; NASM is available from http://nasm.sourceforge.net/ or
 ; http://sourceforge.net/project/showfiles.php?group_id=6208
-;
-; [TAB8]
 
 %include "jsimdext.inc"
 
@@ -38,14 +36,23 @@
 
     xor         rdi, rdi                ; simd support flag
 
+    ; Assume that all x86-64 processors support SSE & SSE2 instructions
+    or          rdi, JSIMD_SSE2
+    or          rdi, JSIMD_SSE
+
+    ; Check whether CPUID leaf 07H is supported
+    ; (leaf 07H is used to check for AVX2 instruction support)
+    mov         rax, 0
+    cpuid
+    cmp         rax, 7
+    jl          short .return           ; Maximum leaf < 07H
+
     ; Check for AVX2 instruction support
     mov         rax, 7
     xor         rcx, rcx
     cpuid
     mov         rax, rbx                ; rax = Extended feature flags
 
-    or          rdi, JSIMD_SSE2
-    or          rdi, JSIMD_SSE
     test        rax, 1<<5               ; bit5:AVX2
     jz          short .return
 
@@ -60,9 +67,10 @@
 
     xor         rcx, rcx
     xgetbv
-    test        rax, 6                  ; O/S does not manage XMM/YMM state
+    and         rax, 6
+    cmp         rax, 6                  ; O/S does not manage XMM/YMM state
                                         ; using XSAVE
-    jz          short .return
+    jnz         short .return
 
     or          rdi, JSIMD_AVX2
 
diff --git a/src/third_party/libjpeg-turbo/structure.txt b/src/third_party/libjpeg-turbo/structure.txt
index f69c9d8..15b8d37 100644
--- a/src/third_party/libjpeg-turbo/structure.txt
+++ b/src/third_party/libjpeg-turbo/structure.txt
@@ -89,12 +89,12 @@
 The compressor and decompressor are each divided into two main sections:
 the JPEG compressor or decompressor proper, and the preprocessing or
 postprocessing functions.  The interface between these two sections is the
-image data that the official JPEG spec regards as its input or output: this
-data is in the colorspace to be used for compression, and it is downsampled
-to the sampling factors to be used.  The preprocessing and postprocessing
-steps are responsible for converting a normal image representation to or from
-this form.  (Those few applications that want to deal with YCbCr downsampled
-data can skip the preprocessing or postprocessing step.)
+image data that Rec. ITU-T T.81 | ISO/IEC 10918-1 regards as its input or
+output: this data is in the colorspace to be used for compression, and it is
+downsampled to the sampling factors to be used.  The preprocessing and
+postprocessing steps are responsible for converting a normal image
+representation to or from this form.  (Those few applications that want to deal
+with YCbCr downsampled data can skip the preprocessing or postprocessing step.)
 
 Looking more closely, the compressor library contains the following main
 elements:
@@ -141,22 +141,22 @@
 
 
 Note: it is convenient to regard edge expansion (padding to block boundaries)
-as a preprocessing/postprocessing function, even though the JPEG spec includes
-it in compression/decompression.  We do this because downsampling/upsampling
-can be simplified a little if they work on padded data: it's not necessary to
-have special cases at the right and bottom edges.  Therefore the interface
-buffer is always an integral number of blocks wide and high, and we expect
-compression preprocessing to pad the source data properly.  Padding will occur
-only to the next block (8-sample) boundary.  In an interleaved-scan situation,
-additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
-disassembly logic will create or discard these blocks internally.  (This is
-advantageous for speed reasons, since we avoid DCTing the dummy blocks.
-It also permits a small reduction in file size, because the compressor can
-choose dummy block contents so as to minimize their size in compressed form.
-Finally, it makes the interface buffer specification independent of whether
-the file is actually interleaved or not.)  Applications that wish to deal
-directly with the downsampled data must provide similar buffering and padding
-for odd-sized images.
+as a preprocessing/postprocessing function, even though
+Rec. ITU-T T.81 | ISO/IEC 10918-1 includes it in compression/decompression.  We
+do this because downsampling/upsampling can be simplified a little if they work
+on padded data: it's not necessary to have special cases at the right and
+bottom edges.  Therefore the interface buffer is always an integral number of
+blocks wide and high, and we expect compression preprocessing to pad the source
+data properly.  Padding will occur only to the next block (8-sample) boundary.
+In an interleaved-scan situation, additional dummy blocks may be used to fill
+out MCUs, but the MCU assembly and disassembly logic will create or discard
+these blocks internally.  (This is advantageous for speed reasons, since we
+avoid DCTing the dummy blocks.  It also permits a small reduction in file size,
+because the compressor can choose dummy block contents so as to minimize their
+size in compressed form.  Finally, it makes the interface buffer specification
+independent of whether the file is actually interleaved or not.)  Applications
+that wish to deal directly with the downsampled data must provide similar
+buffering and padding for odd-sized images.
 
 
 *** Poor man's object-oriented programming ***
@@ -548,13 +548,9 @@
     typedef JSAMPROW *JSAMPARRAY;       ptr to a list of rows
     typedef JSAMPARRAY *JSAMPIMAGE;     ptr to a list of color-component arrays
 
-The basic element type JSAMPLE will typically be one of unsigned char,
-(signed) char, or short.  Short will be used if samples wider than 8 bits are
-to be supported (this is a compile-time option).  Otherwise, unsigned char is
-used if possible.  If the compiler only supports signed chars, then it is
-necessary to mask off the value when reading.  Thus, all reads of JSAMPLE
-values must be coded as "GETJSAMPLE(value)", where the macro will be defined
-as "((value) & 0xFF)" on signed-char machines and "((int) (value))" elsewhere.
+The basic element type JSAMPLE will be one of unsigned char or short.  Short
+will be used if samples wider than 8 bits are to be supported (this is a
+compile-time option).  Otherwise, unsigned char is used.
 
 With these conventions, JSAMPLE values can be assumed to be >= 0.  This helps
 simplify correct rounding during downsampling, etc.  The JPEG standard's
@@ -587,7 +583,7 @@
 is helpful when dealing with noninterleaved JPEG files.
 
 In general, a specific sample value is accessed by code such as
-        GETJSAMPLE(image[colorcomponent][row][col])
+        image[colorcomponent][row][col]
 where col is measured from the image left edge, but row is measured from the
 first sample row currently in memory.  Either of the first two indexings can
 be precomputed by copying the relevant pointer.
diff --git a/src/third_party/libjpeg-turbo/testimages/test.scan b/src/third_party/libjpeg-turbo/testimages/test.scan
new file mode 100644
index 0000000..2a8ea7f
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/test.scan
@@ -0,0 +1,8 @@
+0 1 2: 0 0 0 0;
+0: 1 9 0 0;
+0: 10 41 0 2;
+0: 10 41 2 1;
+0: 10 41 1 0;
+0: 42 63 0 0;
+1: 1 63 0 0;
+2: 1 63 0 0;
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog.jpg b/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog.jpg
new file mode 100644
index 0000000..6da8d52
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog_sse.jpg b/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog_sse.jpg
new file mode 100644
index 0000000..7a27f4b
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_3x2_float_prog_sse.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_3x2_ifast_prog.jpg b/src/third_party/libjpeg-turbo/testimages/testout_3x2_ifast_prog.jpg
new file mode 100644
index 0000000..934a9f1
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_3x2_ifast_prog.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_420_islow_prog.jpg b/src/third_party/libjpeg-turbo/testimages/testout_420_islow_prog.jpg
new file mode 100644
index 0000000..968a90e
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_420_islow_prog.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_420_q100_ifast_prog.jpg b/src/third_party/libjpeg-turbo/testimages/testout_420_q100_ifast_prog.jpg
new file mode 100644
index 0000000..13e0503
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_420_q100_ifast_prog.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_422_ifast_opt.jpg b/src/third_party/libjpeg-turbo/testimages/testout_422_ifast_opt.jpg
new file mode 100644
index 0000000..bc2ae71
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_422_ifast_opt.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_444_islow.jpg b/src/third_party/libjpeg-turbo/testimages/testout_444_islow.jpg
new file mode 100644
index 0000000..483551c
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_444_islow.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_444_islow_ari.jpg b/src/third_party/libjpeg-turbo/testimages/testout_444_islow_ari.jpg
new file mode 100644
index 0000000..5929b84
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_444_islow_ari.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_444_islow_prog.jpg b/src/third_party/libjpeg-turbo/testimages/testout_444_islow_prog.jpg
new file mode 100644
index 0000000..49b59f5
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_444_islow_prog.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_gray_islow.jpg b/src/third_party/libjpeg-turbo/testimages/testout_gray_islow.jpg
new file mode 100644
index 0000000..95505a2
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_gray_islow.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/testimages/testout_rgb_islow.jpg b/src/third_party/libjpeg-turbo/testimages/testout_rgb_islow.jpg
new file mode 100644
index 0000000..1d35986
--- /dev/null
+++ b/src/third_party/libjpeg-turbo/testimages/testout_rgb_islow.jpg
Binary files differ
diff --git a/src/third_party/libjpeg-turbo/tjbench.c b/src/third_party/libjpeg-turbo/tjbench.c
index 3ee933a..97475ec 100644
--- a/src/third_party/libjpeg-turbo/tjbench.c
+++ b/src/third_party/libjpeg-turbo/tjbench.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C)2009-2018 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2009-2019, 2021 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -26,37 +26,35 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef STARBOARD
-#include "starboard/client_porting/poem/stdio_poem.h"
-#else
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <math.h>
-#endif
 #include <errno.h>
+#include <limits.h>
 #include <cdjpeg.h>
 #include "./tjutil.h"
 #include "./turbojpeg.h"
 
 
-#define _throw(op, err) { \
-  printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \
+#define THROW(op, err) { \
+  fprintf(stderr, "ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \
   retval = -1;  goto bailout; \
 }
-#define _throwunix(m)  _throw(m, strerror(errno))
+#define THROW_UNIX(m)  THROW(m, strerror(errno))
 
-char tjErrorStr[JMSG_LENGTH_MAX] = "\0", tjErrorMsg[JMSG_LENGTH_MAX] = "\0";
-int tjErrorLine = -1, tjErrorCode = -1;
+static char tjErrorStr[JMSG_LENGTH_MAX] = "\0",
+            tjErrorMsg[JMSG_LENGTH_MAX] = "\0";
+static int tjErrorLine = -1, tjErrorCode = -1;
 
-#define _throwtjg(m) { \
-  printf("ERROR in line %d while %s:\n%s\n", __LINE__, m, \
-         tjGetErrorStr2(NULL)); \
+#define THROW_TJG(m) { \
+  fprintf(stderr, "ERROR in line %d while %s:\n%s\n", __LINE__, m, \
+          tjGetErrorStr2(NULL)); \
   retval = -1;  goto bailout; \
 }
 
-#define _throwtj(m) { \
+#define THROW_TJ(m) { \
   int _tjErrorCode = tjGetErrorCode(handle); \
   char *_tjErrorStr = tjGetErrorStr2(handle); \
   \
@@ -64,42 +62,44 @@
     if (strncmp(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX) || \
         strncmp(tjErrorMsg, m, JMSG_LENGTH_MAX) || \
         tjErrorCode != _tjErrorCode || tjErrorLine != __LINE__) { \
-      strncpy(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX); \
-      strncpy(tjErrorMsg, m, JMSG_LENGTH_MAX); \
+      strncpy(tjErrorStr, _tjErrorStr, JMSG_LENGTH_MAX - 1); \
+      strncpy(tjErrorMsg, m, JMSG_LENGTH_MAX - 1); \
       tjErrorCode = _tjErrorCode; \
       tjErrorLine = __LINE__; \
-      printf("WARNING in line %d while %s:\n%s\n", __LINE__, m, _tjErrorStr); \
+      fprintf(stderr, "WARNING in line %d while %s:\n%s\n", __LINE__, m, \
+              _tjErrorStr); \
     } \
   } else { \
-    printf("%s in line %d while %s:\n%s\n", \
-           _tjErrorCode == TJERR_WARNING ? "WARNING" : "ERROR", __LINE__, m, \
-           _tjErrorStr); \
+    fprintf(stderr, "%s in line %d while %s:\n%s\n", \
+            _tjErrorCode == TJERR_WARNING ? "WARNING" : "ERROR", __LINE__, m, \
+            _tjErrorStr); \
     retval = -1;  goto bailout; \
   } \
 }
 
-int flags = TJFLAG_NOREALLOC, compOnly = 0, decompOnly = 0, doYUV = 0,
+static int flags = TJFLAG_NOREALLOC, compOnly = 0, decompOnly = 0, doYUV = 0,
   quiet = 0, doTile = 0, pf = TJPF_BGR, yuvPad = 1, doWrite = 1;
-char *ext = "ppm";
-const char *pixFormatStr[TJ_NUMPF] = {
+static char *ext = "ppm";
+static const char *pixFormatStr[TJ_NUMPF] = {
   "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY", "", "", "", "", "CMYK"
 };
-const char *subNameLong[TJ_NUMSAMP] = {
+static const char *subNameLong[TJ_NUMSAMP] = {
   "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
 };
-const char *csName[TJ_NUMCS] = {
+static const char *csName[TJ_NUMCS] = {
   "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
 };
-const char *subName[TJ_NUMSAMP] = {
+static const char *subName[TJ_NUMSAMP] = {
   "444", "422", "420", "GRAY", "440", "411"
 };
-tjscalingfactor *scalingFactors = NULL, sf = { 1, 1 };
-int nsf = 0, xformOp = TJXOP_NONE, xformOpt = 0;
-int (*customFilter) (short *, tjregion, tjregion, int, int, tjtransform *);
-double benchTime = 5.0, warmup = 1.0;
+static tjscalingfactor *scalingFactors = NULL, sf = { 1, 1 };
+static int nsf = 0, xformOp = TJXOP_NONE, xformOpt = 0;
+static int (*customFilter) (short *, tjregion, tjregion, int, int,
+                            tjtransform *);
+static double benchTime = 5.0, warmup = 1.0;
 
 
-char *formatName(int subsamp, int cs, char *buf)
+static char *formatName(int subsamp, int cs, char *buf)
 {
   if (cs == TJCS_YCbCr)
     return (char *)subNameLong[subsamp];
@@ -111,7 +111,7 @@
 }
 
 
-char *sigfig(double val, int figs, char *buf, int len)
+static char *sigfig(double val, int figs, char *buf, int len)
 {
   char format[80];
   int digitsAfterDecimal = figs - (int)ceil(log10(fabs(val)));
@@ -126,9 +126,9 @@
 
 
 /* Custom DCT filter which produces a negative of the image */
-int dummyDCTFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
-                   int componentIndex, int transformIndex,
-                   tjtransform *transform)
+static int dummyDCTFilter(short *coeffs, tjregion arrayRegion,
+                          tjregion planeRegion, int componentIndex,
+                          int transformIndex, tjtransform *transform)
 {
   int i;
 
@@ -139,11 +139,12 @@
 
 
 /* Decompression test */
-int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
-           unsigned long *jpegSize, unsigned char *dstBuf, int w, int h,
-           int subsamp, int jpegQual, char *fileName, int tilew, int tileh)
+static int decomp(unsigned char *srcBuf, unsigned char **jpegBuf,
+                  unsigned long *jpegSize, unsigned char *dstBuf, int w, int h,
+                  int subsamp, int jpegQual, char *fileName, int tilew,
+                  int tileh)
 {
-  char tempStr[1024], sizeStr[20] = "\0", qualStr[6] = "\0", *ptr;
+  char tempStr[1024], sizeStr[24] = "\0", qualStr[13] = "\0", *ptr;
   FILE *file = NULL;
   tjhandle handle = NULL;
   int row, col, iter = 0, dstBufAlloc = 0, retval = 0;
@@ -156,29 +157,34 @@
   unsigned char *dstPtr, *dstPtr2, *yuvBuf = NULL;
 
   if (jpegQual > 0) {
-    snprintf(qualStr, 6, "_Q%d", jpegQual);
-    qualStr[5] = 0;
+    snprintf(qualStr, 13, "_Q%d", jpegQual);
+    qualStr[12] = 0;
   }
 
   if ((handle = tjInitDecompress()) == NULL)
-    _throwtj("executing tjInitDecompress()");
+    THROW_TJ("executing tjInitDecompress()");
 
   if (dstBuf == NULL) {
-    if ((dstBuf = (unsigned char *)malloc(pitch * scaledh)) == NULL)
-      _throwunix("allocating destination buffer");
+    if ((unsigned long long)pitch * (unsigned long long)scaledh >
+        (unsigned long long)((size_t)-1))
+      THROW("allocating destination buffer", "Image is too large");
+    if ((dstBuf = (unsigned char *)malloc((size_t)pitch * scaledh)) == NULL)
+      THROW_UNIX("allocating destination buffer");
     dstBufAlloc = 1;
   }
   /* Set the destination buffer to gray so we know whether the decompressor
      attempted to write to it */
-  memset(dstBuf, 127, pitch * scaledh);
+  memset(dstBuf, 127, (size_t)pitch * scaledh);
 
   if (doYUV) {
     int width = doTile ? tilew : scaledw;
     int height = doTile ? tileh : scaledh;
-    int yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp);
+    unsigned long yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp);
 
+    if (yuvSize == (unsigned long)-1)
+      THROW_TJ("allocating YUV buffer");
     if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
-      _throwunix("allocating YUV buffer");
+      THROW_UNIX("allocating YUV buffer");
     memset(yuvBuf, 127, yuvSize);
   }
 
@@ -190,7 +196,7 @@
     double start = getTime();
 
     for (row = 0, dstPtr = dstBuf; row < ntilesh;
-         row++, dstPtr += pitch * tileh) {
+         row++, dstPtr += (size_t)pitch * tileh) {
       for (col = 0, dstPtr2 = dstPtr; col < ntilesw;
            col++, tile++, dstPtr2 += ps * tilew) {
         int width = doTile ? min(tilew, w - col * tilew) : scaledw;
@@ -201,16 +207,16 @@
 
           if (tjDecompressToYUV2(handle, jpegBuf[tile], jpegSize[tile], yuvBuf,
                                  width, yuvPad, height, flags) == -1)
-            _throwtj("executing tjDecompressToYUV2()");
+            THROW_TJ("executing tjDecompressToYUV2()");
           startDecode = getTime();
           if (tjDecodeYUV(handle, yuvBuf, yuvPad, subsamp, dstPtr2, width,
                           pitch, height, pf, flags) == -1)
-            _throwtj("executing tjDecodeYUV()");
+            THROW_TJ("executing tjDecodeYUV()");
           if (iter >= 0) elapsedDecode += getTime() - startDecode;
         } else if (tjDecompress2(handle, jpegBuf[tile], jpegSize[tile],
                                  dstPtr2, width, pitch, height, pf,
                                  flags) == -1)
-          _throwtj("executing tjDecompress2()");
+          THROW_TJ("executing tjDecompress2()");
       }
     }
     elapsed += getTime() - start;
@@ -224,39 +230,41 @@
   }
   if (doYUV) elapsed -= elapsedDecode;
 
-  if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()");
+  if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()");
   handle = NULL;
 
   if (quiet) {
-    printf("%-6s%s",
-           sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
-                  tempStr, 1024),
+    fprintf(stderr, "%-6s%s",
+            sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
+                   tempStr, 1024),
            quiet == 2 ? "\n" : "  ");
     if (doYUV)
-      printf("%s\n",
-             sigfig((double)(w * h) / 1000000. * (double)iter / elapsedDecode,
-                    4, tempStr, 1024));
-    else if (quiet != 2) printf("\n");
+      fprintf(stderr, "%s\n",
+              sigfig((double)(w * h) / 1000000. * (double)iter / elapsedDecode,
+                     4, tempStr, 1024));
+    else if (quiet != 2) fprintf(stderr, "\n");
   } else {
-    printf("%s --> Frame rate:         %f fps\n",
-           doYUV ? "Decomp to YUV" : "Decompress   ", (double)iter / elapsed);
-    printf("                  Throughput:         %f Megapixels/sec\n",
-           (double)(w * h) / 1000000. * (double)iter / elapsed);
+    fprintf(stderr, "%s --> Frame rate:         %f fps\n",
+            doYUV ? "Decomp to YUV" : "Decompress   ", (double)iter / elapsed);
+    fprintf(stderr,
+            "                  Throughput:         %f Megapixels/sec\n",
+            (double)(w * h) / 1000000. * (double)iter / elapsed);
     if (doYUV) {
-      printf("YUV Decode    --> Frame rate:         %f fps\n",
-             (double)iter / elapsedDecode);
-      printf("                  Throughput:         %f Megapixels/sec\n",
-             (double)(w * h) / 1000000. * (double)iter / elapsedDecode);
+      fprintf(stderr, "YUV Decode    --> Frame rate:         %f fps\n",
+              (double)iter / elapsedDecode);
+      fprintf(stderr,
+              "                  Throughput:         %f Megapixels/sec\n",
+              (double)(w * h) / 1000000. * (double)iter / elapsedDecode);
     }
   }
 
   if (!doWrite) goto bailout;
 
   if (sf.num != 1 || sf.denom != 1)
-    snprintf(sizeStr, 20, "%d_%d", sf.num, sf.denom);
+    snprintf(sizeStr, 24, "%d_%d", sf.num, sf.denom);
   else if (tilew != w || tileh != h)
-    snprintf(sizeStr, 20, "%dx%d", tilew, tileh);
-  else snprintf(sizeStr, 20, "full");
+    snprintf(sizeStr, 24, "%dx%d", tilew, tileh);
+  else snprintf(sizeStr, 24, "full");
   if (decompOnly)
     snprintf(tempStr, 1024, "%s_%s.%s", fileName, sizeStr, ext);
   else
@@ -264,19 +272,19 @@
              qualStr, sizeStr, ext);
 
   if (tjSaveImage(tempStr, dstBuf, scaledw, 0, scaledh, pf, flags) == -1)
-    _throwtjg("saving bitmap");
+    THROW_TJG("saving bitmap");
   ptr = strrchr(tempStr, '.');
   snprintf(ptr, 1024 - (ptr - tempStr), "-err.%s", ext);
   if (srcBuf && sf.num == 1 && sf.denom == 1) {
-    if (!quiet) printf("Compression error written to %s.\n", tempStr);
+    if (!quiet) fprintf(stderr, "Compression error written to %s.\n", tempStr);
     if (subsamp == TJ_GRAYSCALE) {
-      int index, index2;
+      unsigned long index, index2;
 
       for (row = 0, index = 0; row < h; row++, index += pitch) {
         for (col = 0, index2 = index; col < w; col++, index2 += ps) {
-          int rindex = index2 + tjRedOffset[pf];
-          int gindex = index2 + tjGreenOffset[pf];
-          int bindex = index2 + tjBlueOffset[pf];
+          unsigned long rindex = index2 + tjRedOffset[pf];
+          unsigned long gindex = index2 + tjGreenOffset[pf];
+          unsigned long bindex = index2 + tjBlueOffset[pf];
           int y = (int)((double)srcBuf[rindex] * 0.299 +
                         (double)srcBuf[gindex] * 0.587 +
                         (double)srcBuf[bindex] * 0.114 + 0.5);
@@ -295,20 +303,20 @@
             abs(dstBuf[pitch * row + col] - srcBuf[pitch * row + col]);
     }
     if (tjSaveImage(tempStr, dstBuf, w, 0, h, pf, flags) == -1)
-      _throwtjg("saving bitmap");
+      THROW_TJG("saving bitmap");
   }
 
 bailout:
   if (file) fclose(file);
   if (handle) tjDestroy(handle);
-  if (dstBuf && dstBufAlloc) free(dstBuf);
-  if (yuvBuf) free(yuvBuf);
+  if (dstBufAlloc) free(dstBuf);
+  free(yuvBuf);
   return retval;
 }
 
 
-int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual,
-             char *fileName)
+static int fullTest(unsigned char *srcBuf, int w, int h, int subsamp,
+                    int jpegQual, char *fileName)
 {
   char tempStr[1024], tempStr2[80];
   FILE *file = NULL;
@@ -317,19 +325,22 @@
     *srcPtr2;
   double start, elapsed, elapsedEncode;
   int totalJpegSize = 0, row, col, i, tilew = w, tileh = h, retval = 0;
-  int iter, yuvSize = 0;
-  unsigned long *jpegSize = NULL;
+  int iter;
+  unsigned long *jpegSize = NULL, yuvSize = 0;
   int ps = tjPixelSize[pf];
   int ntilesw = 1, ntilesh = 1, pitch = w * ps;
   const char *pfStr = pixFormatStr[pf];
 
-  if ((tmpBuf = (unsigned char *)malloc(pitch * h)) == NULL)
-    _throwunix("allocating temporary image buffer");
+  if ((unsigned long long)pitch * (unsigned long long)h >
+      (unsigned long long)((size_t)-1))
+    THROW("allocating temporary image buffer", "Image is too large");
+  if ((tmpBuf = (unsigned char *)malloc((size_t)pitch * h)) == NULL)
+    THROW_UNIX("allocating temporary image buffer");
 
   if (!quiet)
-    printf(">>>>>  %s (%s) <--> JPEG %s Q%d  <<<<<\n", pfStr,
-           (flags & TJFLAG_BOTTOMUP) ? "Bottom-up" : "Top-down",
-           subNameLong[subsamp], jpegQual);
+    fprintf(stderr, ">>>>>  %s (%s) <--> JPEG %s Q%d  <<<<<\n", pfStr,
+            (flags & TJFLAG_BOTTOMUP) ? "Bottom-up" : "Top-down",
+            subNameLong[subsamp], jpegQual);
 
   for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ;
        tilew *= 2, tileh *= 2) {
@@ -340,34 +351,38 @@
 
     if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) *
                                             ntilesw * ntilesh)) == NULL)
-      _throwunix("allocating JPEG tile array");
+      THROW_UNIX("allocating JPEG tile array");
     memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh);
     if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) *
                                             ntilesw * ntilesh)) == NULL)
-      _throwunix("allocating JPEG size array");
+      THROW_UNIX("allocating JPEG size array");
     memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh);
 
     if ((flags & TJFLAG_NOREALLOC) != 0)
       for (i = 0; i < ntilesw * ntilesh; i++) {
+        if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX)
+          THROW("getting buffer size", "Image is too large");
         if ((jpegBuf[i] = (unsigned char *)
                           tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL)
-          _throwunix("allocating JPEG tiles");
+          THROW_UNIX("allocating JPEG tiles");
       }
 
     /* Compression test */
     if (quiet == 1)
-      printf("%-4s (%s)  %-5s    %-3d   ", pfStr,
-             (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD", subNameLong[subsamp],
-             jpegQual);
+      fprintf(stderr, "%-4s (%s)  %-5s    %-3d   ", pfStr,
+              (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD", subNameLong[subsamp],
+              jpegQual);
     for (i = 0; i < h; i++)
       memcpy(&tmpBuf[pitch * i], &srcBuf[w * ps * i], w * ps);
     if ((handle = tjInitCompress()) == NULL)
-      _throwtj("executing tjInitCompress()");
+      THROW_TJ("executing tjInitCompress()");
 
     if (doYUV) {
       yuvSize = tjBufSizeYUV2(tilew, yuvPad, tileh, subsamp);
+      if (yuvSize == (unsigned long)-1)
+        THROW_TJ("allocating YUV buffer");
       if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
-        _throwunix("allocating YUV buffer");
+        THROW_UNIX("allocating YUV buffer");
       memset(yuvBuf, 127, yuvSize);
     }
 
@@ -391,17 +406,17 @@
 
             if (tjEncodeYUV3(handle, srcPtr2, width, pitch, height, pf, yuvBuf,
                              yuvPad, subsamp, flags) == -1)
-              _throwtj("executing tjEncodeYUV3()");
+              THROW_TJ("executing tjEncodeYUV3()");
             if (iter >= 0) elapsedEncode += getTime() - startEncode;
             if (tjCompressFromYUV(handle, yuvBuf, width, yuvPad, height,
                                   subsamp, &jpegBuf[tile], &jpegSize[tile],
                                   jpegQual, flags) == -1)
-              _throwtj("executing tjCompressFromYUV()");
+              THROW_TJ("executing tjCompressFromYUV()");
           } else {
             if (tjCompress2(handle, srcPtr2, width, pitch, height, pf,
                             &jpegBuf[tile], &jpegSize[tile], subsamp, jpegQual,
                             flags) == -1)
-              _throwtj("executing tjCompress2()");
+              THROW_TJ("executing tjCompress2()");
           }
           totalJpegSize += jpegSize[tile];
         }
@@ -417,58 +432,64 @@
     }
     if (doYUV) elapsed -= elapsedEncode;
 
-    if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()");
+    if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()");
     handle = NULL;
 
-    if (quiet == 1) printf("%-5d  %-5d   ", tilew, tileh);
+    if (quiet == 1) fprintf(stderr, "%-5d  %-5d   ", tilew, tileh);
     if (quiet) {
       if (doYUV)
-        printf("%-6s%s",
-               sigfig((double)(w * h) / 1000000. *
-                      (double)iter / elapsedEncode, 4, tempStr, 1024),
-               quiet == 2 ? "\n" : "  ");
-      printf("%-6s%s",
-             sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
-                    tempStr, 1024),
-             quiet == 2 ? "\n" : "  ");
-      printf("%-6s%s",
-             sigfig((double)(w * h * ps) / (double)totalJpegSize, 4, tempStr2,
-                    80),
-             quiet == 2 ? "\n" : "  ");
+        fprintf(stderr, "%-6s%s",
+                sigfig((double)(w * h) / 1000000. *
+                       (double)iter / elapsedEncode, 4, tempStr, 1024),
+                quiet == 2 ? "\n" : "  ");
+      fprintf(stderr, "%-6s%s",
+              sigfig((double)(w * h) / 1000000. * (double)iter / elapsed, 4,
+                     tempStr, 1024),
+              quiet == 2 ? "\n" : "  ");
+      fprintf(stderr, "%-6s%s",
+              sigfig((double)(w * h * ps) / (double)totalJpegSize, 4, tempStr2,
+                     80),
+              quiet == 2 ? "\n" : "  ");
     } else {
-      printf("\n%s size: %d x %d\n", doTile ? "Tile" : "Image", tilew, tileh);
+      fprintf(stderr, "\n%s size: %d x %d\n", doTile ? "Tile" : "Image", tilew,
+              tileh);
       if (doYUV) {
-        printf("Encode YUV    --> Frame rate:         %f fps\n",
-               (double)iter / elapsedEncode);
-        printf("                  Output image size:  %d bytes\n", yuvSize);
-        printf("                  Compression ratio:  %f:1\n",
-               (double)(w * h * ps) / (double)yuvSize);
-        printf("                  Throughput:         %f Megapixels/sec\n",
-               (double)(w * h) / 1000000. * (double)iter / elapsedEncode);
-        printf("                  Output bit stream:  %f Megabits/sec\n",
-               (double)yuvSize * 8. / 1000000. * (double)iter / elapsedEncode);
+        fprintf(stderr, "Encode YUV    --> Frame rate:         %f fps\n",
+                (double)iter / elapsedEncode);
+        fprintf(stderr, "                  Output image size:  %lu bytes\n",
+                yuvSize);
+        fprintf(stderr, "                  Compression ratio:  %f:1\n",
+                (double)(w * h * ps) / (double)yuvSize);
+        fprintf(stderr,
+                "                  Throughput:         %f Megapixels/sec\n",
+                (double)(w * h) / 1000000. * (double)iter / elapsedEncode);
+        fprintf(stderr,
+                "                  Output bit stream:  %f Megabits/sec\n",
+                (double)yuvSize * 8. / 1000000. * (double)iter / elapsedEncode);
       }
-      printf("%s --> Frame rate:         %f fps\n",
-             doYUV ? "Comp from YUV" : "Compress     ",
-             (double)iter / elapsed);
-      printf("                  Output image size:  %d bytes\n",
-             totalJpegSize);
-      printf("                  Compression ratio:  %f:1\n",
-             (double)(w * h * ps) / (double)totalJpegSize);
-      printf("                  Throughput:         %f Megapixels/sec\n",
-             (double)(w * h) / 1000000. * (double)iter / elapsed);
-      printf("                  Output bit stream:  %f Megabits/sec\n",
-             (double)totalJpegSize * 8. / 1000000. * (double)iter / elapsed);
+      fprintf(stderr, "%s --> Frame rate:         %f fps\n",
+              doYUV ? "Comp from YUV" : "Compress     ",
+              (double)iter / elapsed);
+      fprintf(stderr, "                  Output image size:  %d bytes\n",
+              totalJpegSize);
+      fprintf(stderr, "                  Compression ratio:  %f:1\n",
+              (double)(w * h * ps) / (double)totalJpegSize);
+      fprintf(stderr,
+              "                  Throughput:         %f Megapixels/sec\n",
+              (double)(w * h) / 1000000. * (double)iter / elapsed);
+      fprintf(stderr,
+              "                  Output bit stream:  %f Megabits/sec\n",
+              (double)totalJpegSize * 8. / 1000000. * (double)iter / elapsed);
     }
     if (tilew == w && tileh == h && doWrite) {
       snprintf(tempStr, 1024, "%s_%s_Q%d.jpg", fileName, subName[subsamp],
                jpegQual);
       if ((file = fopen(tempStr, "wb")) == NULL)
-        _throwunix("opening reference image");
+        THROW_UNIX("opening reference image");
       if (fwrite(jpegBuf[0], jpegSize[0], 1, file) != 1)
-        _throwunix("writing reference image");
+        THROW_UNIX("writing reference image");
       fclose(file);  file = NULL;
-      if (!quiet) printf("Reference image written to %s\n", tempStr);
+      if (!quiet) fprintf(stderr, "Reference image written to %s\n", tempStr);
     }
 
     /* Decompression test */
@@ -476,10 +497,10 @@
       if (decomp(srcBuf, jpegBuf, jpegSize, tmpBuf, w, h, subsamp, jpegQual,
                  fileName, tilew, tileh) == -1)
         goto bailout;
-    }
+    } else if (quiet == 1) fprintf(stderr, "N/A\n");
 
     for (i = 0; i < ntilesw * ntilesh; i++) {
-      if (jpegBuf[i]) tjFree(jpegBuf[i]);
+      tjFree(jpegBuf[i]);
       jpegBuf[i] = NULL;
     }
     free(jpegBuf);  jpegBuf = NULL;
@@ -492,23 +513,21 @@
   }
 
 bailout:
-  if (file) { fclose(file);  file = NULL; }
+  if (file) fclose(file);
   if (jpegBuf) {
-    for (i = 0; i < ntilesw * ntilesh; i++) {
-      if (jpegBuf[i]) tjFree(jpegBuf[i]);
-      jpegBuf[i] = NULL;
-    }
-    free(jpegBuf);  jpegBuf = NULL;
+    for (i = 0; i < ntilesw * ntilesh; i++)
+      tjFree(jpegBuf[i]);
   }
-  if (yuvBuf) { free(yuvBuf);  yuvBuf = NULL; }
-  if (jpegSize) { free(jpegSize);  jpegSize = NULL; }
-  if (tmpBuf) { free(tmpBuf);  tmpBuf = NULL; }
-  if (handle) { tjDestroy(handle);  handle = NULL; }
+  free(jpegBuf);
+  free(yuvBuf);
+  free(jpegSize);
+  free(tmpBuf);
+  if (handle) tjDestroy(handle);
   return retval;
 }
 
 
-int decompTest(char *fileName)
+static int decompTest(char *fileName)
 {
   FILE *file = NULL;
   tjhandle handle = NULL;
@@ -525,43 +544,47 @@
   int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
 
   if ((file = fopen(fileName, "rb")) == NULL)
-    _throwunix("opening file");
+    THROW_UNIX("opening file");
   if (fseek(file, 0, SEEK_END) < 0 ||
       (srcSize = ftell(file)) == (unsigned long)-1)
-    _throwunix("determining file size");
+    THROW_UNIX("determining file size");
   if ((srcBuf = (unsigned char *)malloc(srcSize)) == NULL)
-    _throwunix("allocating memory");
+    THROW_UNIX("allocating memory");
   if (fseek(file, 0, SEEK_SET) < 0)
-    _throwunix("setting file position");
+    THROW_UNIX("setting file position");
   if (fread(srcBuf, srcSize, 1, file) < 1)
-    _throwunix("reading JPEG data");
+    THROW_UNIX("reading JPEG data");
   fclose(file);  file = NULL;
 
   temp = strrchr(fileName, '.');
   if (temp != NULL) *temp = '\0';
 
   if ((handle = tjInitTransform()) == NULL)
-    _throwtj("executing tjInitTransform()");
+    THROW_TJ("executing tjInitTransform()");
   if (tjDecompressHeader3(handle, srcBuf, srcSize, &w, &h, &subsamp,
                           &cs) == -1)
-    _throwtj("executing tjDecompressHeader3()");
+    THROW_TJ("executing tjDecompressHeader3()");
+  if (w < 1 || h < 1)
+    THROW("reading JPEG header", "Invalid image dimensions");
   if (cs == TJCS_YCCK || cs == TJCS_CMYK) {
     pf = TJPF_CMYK;  ps = tjPixelSize[pf];
   }
 
   if (quiet == 1) {
-    printf("All performance values in Mpixels/sec\n\n");
-    printf("Bitmap     JPEG   JPEG     %s  %s   Xform   Comp    Decomp  ",
-           doTile ? "Tile " : "Image", doTile ? "Tile " : "Image");
-    if (doYUV) printf("Decode");
-    printf("\n");
-    printf("Format     CS     Subsamp  Width  Height  Perf    Ratio   Perf    ");
-    if (doYUV) printf("Perf");
-    printf("\n\n");
+    fprintf(stderr, "All performance values in Mpixels/sec\n\n");
+    fprintf(stderr,
+            "Bitmap     JPEG   JPEG     %s  %s   Xform   Comp    Decomp  ",
+            doTile ? "Tile " : "Image", doTile ? "Tile " : "Image");
+    if (doYUV) fprintf(stderr, "Decode");
+    fprintf(stderr, "\n");
+    fprintf(stderr,
+        "Format     CS     Subsamp  Width  Height  Perf    Ratio   Perf    ");
+    if (doYUV) fprintf(stderr, "Perf");
+    fprintf(stderr, "\n\n");
   } else if (!quiet)
-    printf(">>>>>  JPEG %s --> %s (%s)  <<<<<\n",
-           formatName(subsamp, cs, tempStr), pixFormatStr[pf],
-           (flags & TJFLAG_BOTTOMUP) ? "Bottom-up" : "Top-down");
+    fprintf(stderr, ">>>>>  JPEG %s --> %s (%s)  <<<<<\n",
+            formatName(subsamp, cs, tempStr), pixFormatStr[pf],
+            (flags & TJFLAG_BOTTOMUP) ? "Bottom-up" : "Top-down");
 
   for (tilew = doTile ? 16 : w, tileh = doTile ? 16 : h; ;
        tilew *= 2, tileh *= 2) {
@@ -572,38 +595,42 @@
 
     if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) *
                                             ntilesw * ntilesh)) == NULL)
-      _throwunix("allocating JPEG tile array");
+      THROW_UNIX("allocating JPEG tile array");
     memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh);
     if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) *
                                             ntilesw * ntilesh)) == NULL)
-      _throwunix("allocating JPEG size array");
+      THROW_UNIX("allocating JPEG size array");
     memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh);
 
-    if ((flags & TJFLAG_NOREALLOC) != 0 || !doTile)
+    if ((flags & TJFLAG_NOREALLOC) != 0 &&
+        (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter))
       for (i = 0; i < ntilesw * ntilesh; i++) {
+        if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX)
+          THROW("getting buffer size", "Image is too large");
         if ((jpegBuf[i] = (unsigned char *)
                           tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL)
-          _throwunix("allocating JPEG tiles");
+          THROW_UNIX("allocating JPEG tiles");
       }
 
     tw = w;  th = h;  ttilew = tilew;  ttileh = tileh;
     if (!quiet) {
-      printf("\n%s size: %d x %d", doTile ? "Tile" : "Image", ttilew, ttileh);
+      fprintf(stderr, "\n%s size: %d x %d", doTile ? "Tile" : "Image", ttilew,
+              ttileh);
       if (sf.num != 1 || sf.denom != 1)
-        printf(" --> %d x %d", TJSCALED(tw, sf), TJSCALED(th, sf));
-      printf("\n");
+        fprintf(stderr, " --> %d x %d", TJSCALED(tw, sf), TJSCALED(th, sf));
+      fprintf(stderr, "\n");
     } else if (quiet == 1) {
-      printf("%-4s (%s)  %-5s  %-5s    ", pixFormatStr[pf],
-             (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD", csName[cs],
-             subNameLong[subsamp]);
-      printf("%-5d  %-5d   ", tilew, tileh);
+      fprintf(stderr, "%-4s (%s)  %-5s  %-5s    ", pixFormatStr[pf],
+              (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD", csName[cs],
+              subNameLong[subsamp]);
+      fprintf(stderr, "%-5d  %-5d   ", tilew, tileh);
     }
 
     tsubsamp = subsamp;
     if (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter) {
       if ((t = (tjtransform *)malloc(sizeof(tjtransform) * ntilesw *
                                      ntilesh)) == NULL)
-        _throwunix("allocating image transform array");
+        THROW_UNIX("allocating image transform array");
 
       if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE ||
           xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) {
@@ -649,7 +676,7 @@
         start = getTime();
         if (tjTransform(handle, srcBuf, srcSize, tntilesw * tntilesh, jpegBuf,
                         jpegSize, t, flags) == -1)
-          _throwtj("executing tjTransform()");
+          THROW_TJ("executing tjTransform()");
         elapsed += getTime() - start;
         if (iter >= 0) {
           iter++;
@@ -666,26 +693,28 @@
         totalJpegSize += jpegSize[tile];
 
       if (quiet) {
-        printf("%-6s%s%-6s%s",
-               sigfig((double)(w * h) / 1000000. / elapsed, 4, tempStr, 80),
-               quiet == 2 ? "\n" : "  ",
-               sigfig((double)(w * h * ps) / (double)totalJpegSize, 4,
-                      tempStr2, 80),
-               quiet == 2 ? "\n" : "  ");
+        fprintf(stderr, "%-6s%s%-6s%s",
+                sigfig((double)(w * h) / 1000000. / elapsed, 4, tempStr, 80),
+                quiet == 2 ? "\n" : "  ",
+                sigfig((double)(w * h * ps) / (double)totalJpegSize, 4,
+                       tempStr2, 80),
+                quiet == 2 ? "\n" : "  ");
       } else if (!quiet) {
-        printf("Transform     --> Frame rate:         %f fps\n",
-               1.0 / elapsed);
-        printf("                  Output image size:  %lu bytes\n",
-               totalJpegSize);
-        printf("                  Compression ratio:  %f:1\n",
-               (double)(w * h * ps) / (double)totalJpegSize);
-        printf("                  Throughput:         %f Megapixels/sec\n",
-               (double)(w * h) / 1000000. / elapsed);
-        printf("                  Output bit stream:  %f Megabits/sec\n",
-               (double)totalJpegSize * 8. / 1000000. / elapsed);
+        fprintf(stderr, "Transform     --> Frame rate:         %f fps\n",
+                1.0 / elapsed);
+        fprintf(stderr, "                  Output image size:  %lu bytes\n",
+                totalJpegSize);
+        fprintf(stderr, "                  Compression ratio:  %f:1\n",
+                (double)(w * h * ps) / (double)totalJpegSize);
+        fprintf(stderr,
+                "                  Throughput:         %f Megapixels/sec\n",
+                (double)(w * h) / 1000000. / elapsed);
+        fprintf(stderr,
+                "                  Output bit stream:  %f Megabits/sec\n",
+                (double)totalJpegSize * 8. / 1000000. / elapsed);
       }
     } else {
-      if (quiet == 1) printf("N/A     N/A     ");
+      if (quiet == 1) fprintf(stderr, "N/A     N/A     ");
       tjFree(jpegBuf[0]);
       jpegBuf[0] = NULL;
       decompsrc = 1;
@@ -698,35 +727,34 @@
                  decompsrc ? &srcSize : jpegSize, NULL, tw, th, tsubsamp, 0,
                  fileName, ttilew, ttileh) == -1)
         goto bailout;
-    } else if (quiet == 1) printf("N/A\n");
+    } else if (quiet == 1) fprintf(stderr, "N/A\n");
 
     for (i = 0; i < ntilesw * ntilesh; i++) {
-      tjFree(jpegBuf[i]);  jpegBuf[i] = NULL;
+      tjFree(jpegBuf[i]);
+      jpegBuf[i] = NULL;
     }
     free(jpegBuf);  jpegBuf = NULL;
-    if (jpegSize) { free(jpegSize);  jpegSize = NULL; }
+    free(jpegSize);  jpegSize = NULL;
 
     if (tilew == w && tileh == h) break;
   }
 
 bailout:
-  if (file) { fclose(file);  file = NULL; }
+  if (file) fclose(file);
   if (jpegBuf) {
-    for (i = 0; i < ntilesw * ntilesh; i++) {
-      if (jpegBuf[i]) tjFree(jpegBuf[i]);
-      jpegBuf[i] = NULL;
-    }
-    free(jpegBuf);  jpegBuf = NULL;
+    for (i = 0; i < ntilesw * ntilesh; i++)
+      tjFree(jpegBuf[i]);
   }
-  if (jpegSize) { free(jpegSize);  jpegSize = NULL; }
-  if (srcBuf) { free(srcBuf);  srcBuf = NULL; }
-  if (t) { free(t);  t = NULL; }
+  free(jpegBuf);
+  free(jpegSize);
+  free(srcBuf);
+  free(t);
   if (handle) { tjDestroy(handle);  handle = NULL; }
   return retval;
 }
 
 
-void usage(char *progName)
+static void usage(char *progName)
 {
   int i;
 
@@ -788,6 +816,8 @@
   printf("-componly = Stop after running compression tests.  Do not test decompression.\n");
   printf("-nowrite = Do not write reference or output images (improves consistency of\n");
   printf("     performance measurements.)\n");
+  printf("-limitscans = Refuse to decompress or transform progressive JPEG images that\n");
+  printf("     have an unreasonably large number of scans\n");
   printf("-stoponwarning = Immediately discontinue the current\n");
   printf("     compression/decompression/transform operation if the underlying codec\n");
   printf("     throws a warning (non-fatal error)\n\n");
@@ -796,8 +826,11 @@
   exit(1);
 }
 
-
+#ifndef GTEST
 int main(int argc, char *argv[])
+#else
+int tjbench(int argc, char *argv[])
+#endif
 {
   unsigned char *srcBuf = NULL;
   int w = 0, h = 0, i, j, minQual = -1, maxQual = -1;
@@ -805,7 +838,7 @@
   int minArg = 2, retval = 0, subsamp = -1;
 
   if ((scalingFactors = tjGetScalingFactors(&nsf)) == NULL || nsf == 0)
-    _throw("executing tjGetScalingFactors()", tjGetErrorStr());
+    THROW("executing tjGetScalingFactors()", tjGetErrorStr());
 
   if (argc < minArg) usage(argv[0]);
 
@@ -816,7 +849,7 @@
       decompOnly = 1;
   }
 
-  printf("\n");
+  fprintf(stderr, "\n");
 
   if (!decompOnly) {
     minArg = 3;
@@ -836,16 +869,16 @@
       if (!strcasecmp(argv[i], "-tile")) {
         doTile = 1;  xformOpt |= TJXOPT_CROP;
       } else if (!strcasecmp(argv[i], "-fastupsample")) {
-        printf("Using fast upsampling code\n\n");
+        fprintf(stderr, "Using fast upsampling code\n\n");
         flags |= TJFLAG_FASTUPSAMPLE;
       } else if (!strcasecmp(argv[i], "-fastdct")) {
-        printf("Using fastest DCT/IDCT algorithm\n\n");
+        fprintf(stderr, "Using fastest DCT/IDCT algorithm\n\n");
         flags |= TJFLAG_FASTDCT;
       } else if (!strcasecmp(argv[i], "-accuratedct")) {
-        printf("Using most accurate DCT/IDCT algorithm\n\n");
+        fprintf(stderr, "Using most accurate DCT/IDCT algorithm\n\n");
         flags |= TJFLAG_ACCURATEDCT;
       } else if (!strcasecmp(argv[i], "-progressive")) {
-        printf("Using progressive entropy coding\n\n");
+        fprintf(stderr, "Using progressive entropy coding\n\n");
         flags |= TJFLAG_PROGRESSIVE;
       } else if (!strcasecmp(argv[i], "-rgb"))
         pf = TJPF_RGB;
@@ -904,34 +937,34 @@
       else if (!strcasecmp(argv[i], "-copynone"))
         xformOpt |= TJXOPT_COPYNONE;
       else if (!strcasecmp(argv[i], "-benchtime") && i < argc - 1) {
-        double temp = atof(argv[++i]);
+        double tempd = atof(argv[++i]);
 
-        if (temp > 0.0) benchTime = temp;
+        if (tempd > 0.0) benchTime = tempd;
         else usage(argv[0]);
       } else if (!strcasecmp(argv[i], "-warmup") && i < argc - 1) {
-        double temp = atof(argv[++i]);
+        double tempd = atof(argv[++i]);
 
-        if (temp >= 0.0) warmup = temp;
+        if (tempd >= 0.0) warmup = tempd;
         else usage(argv[0]);
-        printf("Warmup time = %.1f seconds\n\n", warmup);
+        fprintf(stderr, "Warmup time = %.1f seconds\n\n", warmup);
       } else if (!strcasecmp(argv[i], "-alloc"))
         flags &= (~TJFLAG_NOREALLOC);
       else if (!strcasecmp(argv[i], "-bmp"))
         ext = "bmp";
       else if (!strcasecmp(argv[i], "-yuv")) {
-        printf("Testing YUV planar encoding/decoding\n\n");
+        fprintf(stderr, "Testing YUV planar encoding/decoding\n\n");
         doYUV = 1;
       } else if (!strcasecmp(argv[i], "-yuvpad") && i < argc - 1) {
-        int temp = atoi(argv[++i]);
+        int tempi = atoi(argv[++i]);
 
-        if (temp >= 1) yuvPad = temp;
+        if (tempi >= 1) yuvPad = tempi;
       } else if (!strcasecmp(argv[i], "-subsamp") && i < argc - 1) {
         i++;
         if (toupper(argv[i][0]) == 'G') subsamp = TJSAMP_GRAY;
         else {
-          int temp = atoi(argv[i]);
+          int tempi = atoi(argv[i]);
 
-          switch (temp) {
+          switch (tempi) {
           case 444:  subsamp = TJSAMP_444;  break;
           case 422:  subsamp = TJSAMP_422;  break;
           case 440:  subsamp = TJSAMP_440;  break;
@@ -943,6 +976,8 @@
         compOnly = 1;
       else if (!strcasecmp(argv[i], "-nowrite"))
         doWrite = 0;
+      else if (!strcasecmp(argv[i], "-limitscans"))
+        flags |= TJFLAG_LIMITSCANS;
       else if (!strcasecmp(argv[i], "-stoponwarning"))
         flags |= TJFLAG_STOPONWARNING;
       else usage(argv[0]);
@@ -950,66 +985,66 @@
   }
 
   if ((sf.num != 1 || sf.denom != 1) && doTile) {
-    printf("Disabling tiled compression/decompression tests, because those tests do not\n");
-    printf("work when scaled decompression is enabled.\n");
+    fprintf(stderr, "Disabling tiled compression/decompression tests, because those tests do not\n");
+    fprintf(stderr, "work when scaled decompression is enabled.\n");
     doTile = 0;
   }
 
   if ((flags & TJFLAG_NOREALLOC) == 0 && doTile) {
-    printf("Disabling tiled compression/decompression tests, because those tests do not\n");
-    printf("work when dynamic JPEG buffer allocation is enabled.\n\n");
+    fprintf(stderr, "Disabling tiled compression/decompression tests, because those tests do not\n");
+    fprintf(stderr, "work when dynamic JPEG buffer allocation is enabled.\n\n");
     doTile = 0;
   }
 
   if (!decompOnly) {
     if ((srcBuf = tjLoadImage(argv[1], &w, 1, &h, &pf, flags)) == NULL)
-      _throwtjg("loading bitmap");
+      THROW_TJG("loading bitmap");
     temp = strrchr(argv[1], '.');
     if (temp != NULL) *temp = '\0';
   }
 
   if (quiet == 1 && !decompOnly) {
-    printf("All performance values in Mpixels/sec\n\n");
-    printf("Bitmap     JPEG     JPEG  %s  %s   ",
-           doTile ? "Tile " : "Image", doTile ? "Tile " : "Image");
-    if (doYUV) printf("Encode  ");
-    printf("Comp    Comp    Decomp  ");
-    if (doYUV) printf("Decode");
-    printf("\n");
-    printf("Format     Subsamp  Qual  Width  Height  ");
-    if (doYUV) printf("Perf    ");
-    printf("Perf    Ratio   Perf    ");
-    if (doYUV) printf("Perf");
-    printf("\n\n");
+    fprintf(stderr, "All performance values in Mpixels/sec\n\n");
+    fprintf(stderr, "Bitmap     JPEG     JPEG  %s  %s   ",
+            doTile ? "Tile " : "Image", doTile ? "Tile " : "Image");
+    if (doYUV) fprintf(stderr, "Encode  ");
+    fprintf(stderr, "Comp    Comp    Decomp  ");
+    if (doYUV) fprintf(stderr, "Decode");
+    fprintf(stderr, "\n");
+    fprintf(stderr, "Format     Subsamp  Qual  Width  Height  ");
+    if (doYUV) fprintf(stderr, "Perf    ");
+    fprintf(stderr, "Perf    Ratio   Perf    ");
+    if (doYUV) fprintf(stderr, "Perf");
+    fprintf(stderr, "\n\n");
   }
 
   if (decompOnly) {
     decompTest(argv[1]);
-    printf("\n");
+    fprintf(stderr, "\n");
     goto bailout;
   }
   if (subsamp >= 0 && subsamp < TJ_NUMSAMP) {
     for (i = maxQual; i >= minQual; i--)
       fullTest(srcBuf, w, h, subsamp, i, argv[1]);
-    printf("\n");
+    fprintf(stderr, "\n");
   } else {
     if (pf != TJPF_CMYK) {
       for (i = maxQual; i >= minQual; i--)
         fullTest(srcBuf, w, h, TJSAMP_GRAY, i, argv[1]);
-      printf("\n");
+      fprintf(stderr, "\n");
     }
     for (i = maxQual; i >= minQual; i--)
       fullTest(srcBuf, w, h, TJSAMP_420, i, argv[1]);
-    printf("\n");
+    fprintf(stderr, "\n");
     for (i = maxQual; i >= minQual; i--)
       fullTest(srcBuf, w, h, TJSAMP_422, i, argv[1]);
-    printf("\n");
+    fprintf(stderr, "\n");
     for (i = maxQual; i >= minQual; i--)
       fullTest(srcBuf, w, h, TJSAMP_444, i, argv[1]);
-    printf("\n");
+    fprintf(stderr, "\n");
   }
 
 bailout:
-  if (srcBuf) tjFree(srcBuf);
+  tjFree(srcBuf);
   return retval;
 }
diff --git a/src/third_party/libjpeg-turbo/tjbenchtest.in b/src/third_party/libjpeg-turbo/tjbenchtest.in
old mode 100755
new mode 100644
diff --git a/src/third_party/libjpeg-turbo/tjbenchtest.java.in b/src/third_party/libjpeg-turbo/tjbenchtest.java.in
old mode 100755
new mode 100644
diff --git a/src/third_party/libjpeg-turbo/tjexample.c b/src/third_party/libjpeg-turbo/tjexample.c
deleted file mode 100644
index 1b1064a..0000000
--- a/src/third_party/libjpeg-turbo/tjexample.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C)2011-2012, 2014-2015, 2017 D. R. Commander.
- *                                         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 the libjpeg-turbo Project 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 HOLDERS 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.
- */
-
-/*
- * This program demonstrates how to compress, decompress, and transform JPEG
- * images using the TurboJPEG C API
- */
-
-#ifdef STARBOARD
-#include "starboard/client_porting/poem/stdio_poem.h"
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-#include <errno.h>
-#include <turbojpeg.h>
-
-
-#ifdef _WIN32
-#define strcasecmp  stricmp
-#define strncasecmp  strnicmp
-#endif
-
-#define _throw(action, message) { \
-  printf("ERROR in line %d while %s:\n%s\n", __LINE__, action, message); \
-  retval = -1;  goto bailout; \
-}
-
-#define _throwtj(action)  _throw(action, tjGetErrorStr2(tjInstance))
-
-#define _throwunix(action)  _throw(action, strerror(errno))
-
-#define DEFAULT_SUBSAMP  TJSAMP_444
-#define DEFAULT_QUALITY  95
-
-
-const char *subsampName[TJ_NUMSAMP] = {
-  "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
-};
-
-const char *colorspaceName[TJ_NUMCS] = {
-  "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
-};
-
-tjscalingfactor *scalingFactors = NULL;
-int numScalingFactors = 0;
-
-
-/* DCT filter example.  This produces a negative of the image. */
-
-int customFilter(short *coeffs, tjregion arrayRegion, tjregion planeRegion,
-                 int componentIndex, int transformIndex,
-                 tjtransform *transform)
-{
-  int i;
-
-  for (i = 0; i < arrayRegion.w * arrayRegion.h; i++)
-    coeffs[i] = -coeffs[i];
-
-  return 0;
-}
-
-
-void usage(char *programName)
-{
-  int i;
-
-  printf("\nUSAGE: %s <Input image> <Output image> [options]\n\n",
-         programName);
-
-  printf("Input and output images can be in Windows BMP or PBMPLUS (PPM/PGM) format.  If\n");
-  printf("either filename ends in a .jpg extension, then the TurboJPEG API will be used\n");
-  printf("to compress or decompress the image.\n\n");
-
-  printf("Compression Options (used if the output image is a JPEG image)\n");
-  printf("--------------------------------------------------------------\n\n");
-
-  printf("-subsamp <444|422|420|gray> = Apply this level of chrominance subsampling when\n");
-  printf("     compressing the output image.  The default is to use the same level of\n");
-  printf("     subsampling as in the input image, if the input image is also a JPEG\n");
-  printf("     image, or to use grayscale if the input image is a grayscale non-JPEG\n");
-  printf("     image, or to use %s subsampling otherwise.\n\n",
-         subsampName[DEFAULT_SUBSAMP]);
-
-  printf("-q <1-100> = Compress the output image with this JPEG quality level\n");
-  printf("     (default = %d).\n\n", DEFAULT_QUALITY);
-
-  printf("Decompression Options (used if the input image is a JPEG image)\n");
-  printf("---------------------------------------------------------------\n\n");
-
-  printf("-scale M/N = Scale the input image by a factor of M/N when decompressing it.\n");
-  printf("(M/N = ");
-  for (i = 0; i < numScalingFactors; i++) {
-    printf("%d/%d", scalingFactors[i].num, scalingFactors[i].denom);
-    if (numScalingFactors == 2 && i != numScalingFactors - 1)
-      printf(" or ");
-    else if (numScalingFactors > 2) {
-      if (i != numScalingFactors - 1)
-        printf(", ");
-      if (i == numScalingFactors - 2)
-        printf("or ");
-    }
-  }
-  printf(")\n\n");
-
-  printf("-hflip, -vflip, -transpose, -transverse, -rot90, -rot180, -rot270 =\n");
-  printf("     Perform one of these lossless transform operations on the input image\n");
-  printf("     prior to decompressing it (these options are mutually exclusive.)\n\n");
-
-  printf("-grayscale = Perform lossless grayscale conversion on the input image prior\n");
-  printf("     to decompressing it (can be combined with the other transform operations\n");
-  printf("     above.)\n\n");
-
-  printf("-crop WxH+X+Y = Perform lossless cropping on the input image prior to\n");
-  printf("     decompressing it.  X and Y specify the upper left corner of the cropping\n");
-  printf("     region, and W and H specify the width and height of the cropping region.\n");
-  printf("     X and Y must be evenly divible by the MCU block size (8x8 if the input\n");
-  printf("     image was compressed using no subsampling or grayscale, 16x8 if it was\n");
-  printf("     compressed using 4:2:2 subsampling, or 16x16 if it was compressed using\n");
-  printf("     4:2:0 subsampling.)\n\n");
-
-  printf("General Options\n");
-  printf("---------------\n\n");
-
-  printf("-fastupsample = Use the fastest chrominance upsampling algorithm available in\n");
-  printf("     the underlying codec.\n\n");
-
-  printf("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying\n");
-  printf("     codec.\n\n");
-
-  printf("-accuratedct = Use the most accurate DCT/IDCT algorithms available in the\n");
-  printf("     underlying codec.\n\n");
-
-  exit(1);
-}
-
-
-int main(int argc, char **argv)
-{
-  tjscalingfactor scalingFactor = { 1, 1 };
-  int outSubsamp = -1, outQual = -1;
-  tjtransform xform;
-  int flags = 0;
-  int width, height;
-  char *inFormat, *outFormat;
-  FILE *jpegFile = NULL;
-  unsigned char *imgBuf = NULL, *jpegBuf = NULL;
-  int retval = 0, i, pixelFormat = TJPF_UNKNOWN;
-  tjhandle tjInstance = NULL;
-
-  if ((scalingFactors = tjGetScalingFactors(&numScalingFactors)) == NULL)
-    _throwtj("getting scaling factors");
-  memset(&xform, 0, sizeof(tjtransform));
-
-  if (argc < 3)
-    usage(argv[0]);
-
-  /* Parse arguments. */
-  for (i = 3; i < argc; i++) {
-    if (!strncasecmp(argv[i], "-sc", 3) && i < argc - 1) {
-      int match = 0, temp1 = 0, temp2 = 0, j;
-
-      if (sscanf(argv[++i], "%d/%d", &temp1, &temp2) < 2)
-        usage(argv[0]);
-      for (j = 0; j < numScalingFactors; j++) {
-        if ((double)temp1 / (double)temp2 == (double)scalingFactors[j].num /
-                                             (double)scalingFactors[j].denom) {
-          scalingFactor = scalingFactors[j];
-          match = 1;
-          break;
-        }
-      }
-      if (match != 1)
-        usage(argv[0]);
-    } else if (!strncasecmp(argv[i], "-su", 3) && i < argc - 1) {
-      i++;
-      if (!strncasecmp(argv[i], "g", 1))
-        outSubsamp = TJSAMP_GRAY;
-      else if (!strcasecmp(argv[i], "444"))
-        outSubsamp = TJSAMP_444;
-      else if (!strcasecmp(argv[i], "422"))
-        outSubsamp = TJSAMP_422;
-      else if (!strcasecmp(argv[i], "420"))
-        outSubsamp = TJSAMP_420;
-      else
-        usage(argv[0]);
-    } else if (!strncasecmp(argv[i], "-q", 2) && i < argc - 1) {
-      outQual = atoi(argv[++i]);
-      if (outQual < 1 || outQual > 100)
-        usage(argv[0]);
-    } else if (!strncasecmp(argv[i], "-g", 2))
-      xform.options |= TJXOPT_GRAY;
-    else if (!strcasecmp(argv[i], "-hflip"))
-      xform.op = TJXOP_HFLIP;
-    else if (!strcasecmp(argv[i], "-vflip"))
-      xform.op = TJXOP_VFLIP;
-    else if (!strcasecmp(argv[i], "-transpose"))
-      xform.op = TJXOP_TRANSPOSE;
-    else if (!strcasecmp(argv[i], "-transverse"))
-      xform.op = TJXOP_TRANSVERSE;
-    else if (!strcasecmp(argv[i], "-rot90"))
-      xform.op = TJXOP_ROT90;
-    else if (!strcasecmp(argv[i], "-rot180"))
-      xform.op = TJXOP_ROT180;
-    else if (!strcasecmp(argv[i], "-rot270"))
-      xform.op = TJXOP_ROT270;
-    else if (!strcasecmp(argv[i], "-custom"))
-      xform.customFilter = customFilter;
-    else if (!strncasecmp(argv[i], "-c", 2) && i < argc - 1) {
-      if (sscanf(argv[++i], "%dx%d+%d+%d", &xform.r.w, &xform.r.h, &xform.r.x,
-                 &xform.r.y) < 4 ||
-          xform.r.x < 0 || xform.r.y < 0 || xform.r.w < 1 || xform.r.h < 1)
-        usage(argv[0]);
-      xform.options |= TJXOPT_CROP;
-    } else if (!strcasecmp(argv[i], "-fastupsample")) {
-      printf("Using fast upsampling code\n");
-      flags |= TJFLAG_FASTUPSAMPLE;
-    } else if (!strcasecmp(argv[i], "-fastdct")) {
-      printf("Using fastest DCT/IDCT algorithm\n");
-      flags |= TJFLAG_FASTDCT;
-    } else if (!strcasecmp(argv[i], "-accuratedct")) {
-      printf("Using most accurate DCT/IDCT algorithm\n");
-      flags |= TJFLAG_ACCURATEDCT;
-    } else usage(argv[0]);
-  }
-
-  /* Determine input and output image formats based on file extensions. */
-  inFormat = strrchr(argv[1], '.');
-  outFormat = strrchr(argv[2], '.');
-  if (inFormat == NULL || outFormat == NULL || strlen(inFormat) < 2 ||
-      strlen(outFormat) < 2)
-    usage(argv[0]);
-  inFormat = &inFormat[1];
-  outFormat = &outFormat[1];
-
-  if (!strcasecmp(inFormat, "jpg")) {
-    /* Input image is a JPEG image.  Decompress and/or transform it. */
-    long size;
-    int inSubsamp, inColorspace;
-    int doTransform = (xform.op != TJXOP_NONE || xform.options != 0 ||
-                       xform.customFilter != NULL);
-    unsigned long jpegSize;
-
-    /* Read the JPEG file into memory. */
-    if ((jpegFile = fopen(argv[1], "rb")) == NULL)
-      _throwunix("opening input file");
-    if (fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) ||
-        fseek(jpegFile, 0, SEEK_SET) < 0)
-      _throwunix("determining input file size");
-    if (size == 0)
-      _throw("determining input file size", "Input file contains no data");
-    jpegSize = (unsigned long)size;
-    if ((jpegBuf = (unsigned char *)tjAlloc(jpegSize)) == NULL)
-      _throwunix("allocating JPEG buffer");
-    if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1)
-      _throwunix("reading input file");
-    fclose(jpegFile);  jpegFile = NULL;
-
-    if (doTransform) {
-      /* Transform it. */
-      unsigned char *dstBuf = NULL;  /* Dynamically allocate the JPEG buffer */
-      unsigned long dstSize = 0;
-
-      if ((tjInstance = tjInitTransform()) == NULL)
-        _throwtj("initializing transformer");
-      xform.options |= TJXOPT_TRIM;
-      if (tjTransform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize,
-                      &xform, flags) < 0)
-        _throwtj("transforming input image");
-      tjFree(jpegBuf);
-      jpegBuf = dstBuf;
-      jpegSize = dstSize;
-    } else {
-      if ((tjInstance = tjInitDecompress()) == NULL)
-        _throwtj("initializing decompressor");
-    }
-
-    if (tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height,
-                            &inSubsamp, &inColorspace) < 0)
-      _throwtj("reading JPEG header");
-
-    printf("%s Image:  %d x %d pixels, %s subsampling, %s colorspace\n",
-           (doTransform ? "Transformed" : "Input"), width, height,
-           subsampName[inSubsamp], colorspaceName[inColorspace]);
-
-    if (!strcasecmp(outFormat, "jpg") && doTransform &&
-        scalingFactor.num == 1 && scalingFactor.denom == 1 && outSubsamp < 0 &&
-        outQual < 0) {
-      /* Input image has been transformed, and no re-compression options
-         have been selected.  Write the transformed image to disk and exit. */
-      if ((jpegFile = fopen(argv[2], "wb")) == NULL)
-        _throwunix("opening output file");
-      if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
-        _throwunix("writing output file");
-      fclose(jpegFile);  jpegFile = NULL;
-      goto bailout;
-    }
-
-    /* Scaling and/or a non-JPEG output image format and/or compression options
-       have been selected, so we need to decompress the input/transformed
-       image. */
-    width = TJSCALED(width, scalingFactor);
-    height = TJSCALED(height, scalingFactor);
-    if (outSubsamp < 0)
-      outSubsamp = inSubsamp;
-
-    pixelFormat = TJPF_BGRX;
-    if ((imgBuf = (unsigned char *)tjAlloc(width * height *
-                                           tjPixelSize[pixelFormat])) == NULL)
-      _throwunix("allocating uncompressed image buffer");
-
-    if (tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height,
-                      pixelFormat, flags) < 0)
-      _throwtj("decompressing JPEG image");
-    tjFree(jpegBuf);  jpegBuf = NULL;
-    tjDestroy(tjInstance);  tjInstance = NULL;
-  } else {
-    /* Input image is not a JPEG image.  Load it into memory. */
-    if ((imgBuf = tjLoadImage(argv[1], &width, 1, &height, &pixelFormat,
-                              0)) == NULL)
-      _throwtj("loading input image");
-    if (outSubsamp < 0) {
-      if (pixelFormat == TJPF_GRAY)
-        outSubsamp = TJSAMP_GRAY;
-      else
-        outSubsamp = TJSAMP_444;
-    }
-    printf("Input Image:  %d x %d pixels\n", width, height);
-  }
-
-  printf("Output Image (%s):  %d x %d pixels", outFormat, width, height);
-
-  if (!strcasecmp(outFormat, "jpg")) {
-    /* Output image format is JPEG.  Compress the uncompressed image. */
-    unsigned char *jpegBuf = NULL;  /* Dynamically allocate the JPEG buffer */
-    unsigned long jpegSize = 0;
-
-    if (outQual < 0)
-      outQual = DEFAULT_QUALITY;
-    printf(", %s subsampling, quality = %d\n", subsampName[outSubsamp],
-           outQual);
-
-    if ((tjInstance = tjInitCompress()) == NULL)
-      _throwtj("initializing compressor");
-    if (tjCompress2(tjInstance, imgBuf, width, 0, height, pixelFormat,
-                    &jpegBuf, &jpegSize, outSubsamp, outQual, flags) < 0)
-      _throwtj("compressing image");
-    tjDestroy(tjInstance);  tjInstance = NULL;
-
-    /* Write the JPEG image to disk. */
-    if ((jpegFile = fopen(argv[2], "wb")) == NULL)
-      _throwunix("opening output file");
-    if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1)
-      _throwunix("writing output file");
-    tjDestroy(tjInstance);  tjInstance = NULL;
-    fclose(jpegFile);  jpegFile = NULL;
-    tjFree(jpegBuf);  jpegBuf = NULL;
-  } else {
-    /* Output image format is not JPEG.  Save the uncompressed image
-       directly to disk. */
-    printf("\n");
-    if (tjSaveImage(argv[2], imgBuf, width, 0, height, pixelFormat, 0) < 0)
-      _throwtj("saving output image");
-  }
-
-bailout:
-  if (imgBuf) tjFree(imgBuf);
-  if (tjInstance) tjDestroy(tjInstance);
-  if (jpegBuf) tjFree(jpegBuf);
-  if (jpegFile) fclose(jpegFile);
-  return retval;
-}
diff --git a/src/third_party/libjpeg-turbo/tjexampletest.in b/src/third_party/libjpeg-turbo/tjexampletest.in
deleted file mode 100755
index 0d3047e..0000000
--- a/src/third_party/libjpeg-turbo/tjexampletest.in
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/bash
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-onexit()
-{
-	if [ -d $OUTDIR ]; then
-		rm -rf $OUTDIR
-	fi
-}
-
-runme()
-{
-	echo \*\*\* $*
-	$*
-}
-
-IMAGES="vgl_5674_0098.bmp vgl_6434_0018a.bmp vgl_6548_0026a.bmp nightshot_iso_100.bmp"
-IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages
-OUTDIR=`mktemp -d /tmp/__tjexampletest_output.XXXXXX`
-EXEDIR=@CMAKE_CURRENT_BINARY_DIR@
-
-if [ -d $OUTDIR ]; then
-	rm -rf $OUTDIR
-fi
-mkdir -p $OUTDIR
-
-exec >$EXEDIR/tjexampletest.log
-
-for image in $IMAGES; do
-
-	cp $IMGDIR/$image $OUTDIR
-	basename=`basename $image .bmp`
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -grayscale -outfile $OUTDIR/${basename}_GRAY_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x2 -outfile $OUTDIR/${basename}_420_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x1 -outfile $OUTDIR/${basename}_422_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 1x1 -outfile $OUTDIR/${basename}_444_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -grayscale -outfile $OUTDIR/${basename}_GRAY_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x2 -outfile $OUTDIR/${basename}_420_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x1 -outfile $OUTDIR/${basename}_422_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 1x1 -outfile $OUTDIR/${basename}_444_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	for samp in GRAY 420 422 444; do
-		runme $EXEDIR/djpeg -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_default_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct fast -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_fast_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct int -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_accurate_djpeg.bmp $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
-	done
-	for samp in 420 422; do
-		runme $EXEDIR/djpeg -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_default_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct fast -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_fast_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct int -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_accurate_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
-	done
-
-	# Compression
-	for dct in fast accurate; do
-		for samp in GRAY 420 422 444; do
-			runme $EXEDIR/tjexample $OUTDIR/$image $OUTDIR/${basename}_${samp}_${dct}.jpg -q 95 -subsamp ${samp} -${dct}dct
-			runme cmp $OUTDIR/${basename}_${samp}_${dct}.jpg $OUTDIR/${basename}_${samp}_${dct}_cjpeg.jpg
-		done
-	done
-
-	# Decompression
-	for dct in fast accurate default; do
-		srcdct=${dct}
-		dctarg=-${dct}dct
-		if [ "${dct}" = "default" ]; then
-			srcdct=fast
-			dctarg=
-		fi
-		for samp in GRAY 420 422 444; do
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_${srcdct}.jpg $OUTDIR/${basename}_${samp}_${dct}.bmp ${dctarg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${dct}.bmp $OUTDIR/${basename}_${samp}_${dct}_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${dct}.bmp
-		done
-		for samp in 420 422; do
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_${srcdct}.jpg $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp -fastupsample ${dctarg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp $OUTDIR/${basename}_${samp}_${dct}_nosmooth_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp
-		done
-	done
-
-	# Scaled decompression
-	for scale in 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8; do
-		scalearg=`echo $scale | sed 's/\_/\//g'`
-		for samp in GRAY 420 422 444; do
-			runme $EXEDIR/djpeg -rgb -bmp -scale ${scalearg} -outfile $OUTDIR/${basename}_${samp}_${scale}_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${scale}.bmp -scale ${scalearg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${scale}.bmp $OUTDIR/${basename}_${samp}_${scale}_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${scale}.bmp
-		done
-	done
-
-	# Transforms
-	for samp in GRAY 420 422 444; do
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -flip horizontal -trim -outfile $OUTDIR/${basename}_${samp}_hflip_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -flip vertical -trim -outfile $OUTDIR/${basename}_${samp}_vflip_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -transpose -trim -outfile $OUTDIR/${basename}_${samp}_transpose_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -transverse -trim -outfile $OUTDIR/${basename}_${samp}_transverse_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 90 -trim -outfile $OUTDIR/${basename}_${samp}_rot90_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 180 -trim -outfile $OUTDIR/${basename}_${samp}_rot180_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 270 -trim -outfile $OUTDIR/${basename}_${samp}_rot270_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-	done
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 420 422 444; do
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.jpg -$xform -crop 70x60+16+16
-			runme cmp $OUTDIR/${basename}_${samp}_${xform}.jpg $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme $EXEDIR/djpeg -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -crop 70x60+16+16
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-		for samp in 420 422; do
-			runme $EXEDIR/djpeg -nosmooth -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -crop 70x60+16+16 -fastupsample
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-	done
-
-	# Grayscale transform
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 444 422 420; do
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.jpg -$xform -grayscale -crop 70x60+16+16
-			runme cmp $OUTDIR/${basename}_${samp}_${xform}.jpg $OUTDIR/${basename}_GRAY_${xform}_jpegtran.jpg
-			runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -grayscale -crop 70x60+16+16
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_GRAY_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-	done
-
-	# Transforms with scaling
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 444 422 420; do
-			for scale in 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8; do
-				scalearg=`echo $scale | sed 's/\_/\//g'`
-				runme $EXEDIR/djpeg -rgb -bmp -scale ${scalearg} -outfile $OUTDIR/${basename}_${samp}_${xform}_${scale}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-				runme $EXEDIR/tjexample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp -$xform -scale ${scalearg} -crop 70x60+16+16
-				runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp $OUTDIR/${basename}_${samp}_${xform}_${scale}_jpegtran.bmp
-				rm $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp
-			done
-		done
-	done
-
-done
-
-echo SUCCESS!
diff --git a/src/third_party/libjpeg-turbo/tjexampletest.java.in b/src/third_party/libjpeg-turbo/tjexampletest.java.in
deleted file mode 100755
index d4b63bc..0000000
--- a/src/third_party/libjpeg-turbo/tjexampletest.java.in
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/bash
-
-set -u
-set -e
-trap onexit INT
-trap onexit TERM
-trap onexit EXIT
-
-onexit()
-{
-	if [ -d $OUTDIR ]; then
-		rm -rf $OUTDIR
-	fi
-}
-
-runme()
-{
-	echo \*\*\* $*
-	"$@"
-}
-
-IMAGES="vgl_5674_0098.bmp vgl_6434_0018a.bmp vgl_6548_0026a.bmp nightshot_iso_100.bmp"
-IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages
-OUTDIR=`mktemp -d /tmp/__tjexampletest_java_output.XXXXXX`
-EXEDIR=@CMAKE_CURRENT_BINARY_DIR@
-JAVA="@Java_JAVA_EXECUTABLE@"
-JAVAARGS="-cp $EXEDIR/java/turbojpeg.jar -Djava.library.path=$EXEDIR"
-
-if [ -d $OUTDIR ]; then
-	rm -rf $OUTDIR
-fi
-mkdir -p $OUTDIR
-
-exec >$EXEDIR/tjexampletest-java.log
-
-for image in $IMAGES; do
-
-	cp $IMGDIR/$image $OUTDIR
-	basename=`basename $image .bmp`
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -grayscale -outfile $OUTDIR/${basename}_GRAY_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x2 -outfile $OUTDIR/${basename}_420_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x1 -outfile $OUTDIR/${basename}_422_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 1x1 -outfile $OUTDIR/${basename}_444_fast_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -grayscale -outfile $OUTDIR/${basename}_GRAY_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x2 -outfile $OUTDIR/${basename}_420_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x1 -outfile $OUTDIR/${basename}_422_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	runme $EXEDIR/cjpeg -quality 95 -dct int -sample 1x1 -outfile $OUTDIR/${basename}_444_accurate_cjpeg.jpg $IMGDIR/${basename}.bmp
-	for samp in GRAY 420 422 444; do
-		runme $EXEDIR/djpeg -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_default_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct fast -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_fast_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct int -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_accurate_djpeg.bmp $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
-	done
-	for samp in 420 422; do
-		runme $EXEDIR/djpeg -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_default_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct fast -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_fast_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-		runme $EXEDIR/djpeg -dct int -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_accurate_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
-	done
-
-	# Compression
-	for dct in fast accurate; do
-		for samp in GRAY 420 422 444; do
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/$image $OUTDIR/${basename}_${samp}_${dct}.jpg -q 95 -subsamp ${samp} -${dct}dct
-			runme cmp $OUTDIR/${basename}_${samp}_${dct}.jpg $OUTDIR/${basename}_${samp}_${dct}_cjpeg.jpg
-		done
-	done
-
-	# Decompression
-	for dct in fast accurate default; do
-		srcdct=${dct}
-		dctarg=-${dct}dct
-		if [ "${dct}" = "default" ]; then
-			srcdct=fast
-			dctarg=
-		fi
-		for samp in GRAY 420 422 444; do
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_${srcdct}.jpg $OUTDIR/${basename}_${samp}_${dct}.bmp ${dctarg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${dct}.bmp $OUTDIR/${basename}_${samp}_${dct}_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${dct}.bmp
-		done
-		for samp in 420 422; do
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_${srcdct}.jpg $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp -fastupsample ${dctarg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp $OUTDIR/${basename}_${samp}_${dct}_nosmooth_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${dct}_nosmooth.bmp
-		done
-	done
-
-	# Scaled decompression
-	for scale in 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8; do
-		scalearg=`echo $scale | sed 's/\_/\//g'`
-		for samp in GRAY 420 422 444; do
-			runme $EXEDIR/djpeg -rgb -bmp -scale ${scalearg} -outfile $OUTDIR/${basename}_${samp}_${scale}_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${scale}.bmp -scale ${scalearg}
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${scale}.bmp $OUTDIR/${basename}_${samp}_${scale}_djpeg.bmp
-			rm $OUTDIR/${basename}_${samp}_${scale}.bmp
-		done
-	done
-
-	# Transforms
-	for samp in GRAY 420 422 444; do
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -flip horizontal -trim -outfile $OUTDIR/${basename}_${samp}_hflip_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -flip vertical -trim -outfile $OUTDIR/${basename}_${samp}_vflip_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -transpose -trim -outfile $OUTDIR/${basename}_${samp}_transpose_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -transverse -trim -outfile $OUTDIR/${basename}_${samp}_transverse_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 90 -trim -outfile $OUTDIR/${basename}_${samp}_rot90_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 180 -trim -outfile $OUTDIR/${basename}_${samp}_rot180_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-		runme $EXEDIR/jpegtran -crop 70x60+16+16 -rotate 270 -trim -outfile $OUTDIR/${basename}_${samp}_rot270_jpegtran.jpg $OUTDIR/${basename}_${samp}_fast.jpg
-	done
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 420 422 444; do
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.jpg -$xform -crop 70x60+16+16
-			runme cmp $OUTDIR/${basename}_${samp}_${xform}.jpg $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme $EXEDIR/djpeg -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -crop 70x60+16+16
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-		for samp in 420 422; do
-			runme $EXEDIR/djpeg -nosmooth -rgb -bmp -outfile $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -crop 70x60+16+16 -fastupsample
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-	done
-
-	# Grayscale transform
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 444 422 420; do
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.jpg -$xform -grayscale -crop 70x60+16+16
-			runme cmp $OUTDIR/${basename}_${samp}_${xform}.jpg $OUTDIR/${basename}_GRAY_${xform}_jpegtran.jpg
-			runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}.bmp -$xform -grayscale -crop 70x60+16+16
-			runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}.bmp $OUTDIR/${basename}_GRAY_${xform}_jpegtran.bmp
-			rm $OUTDIR/${basename}_${samp}_${xform}.bmp
-		done
-	done
-
-	# Transforms with scaling
-	for xform in hflip vflip transpose transverse rot90 rot180 rot270; do
-		for samp in GRAY 444 422 420; do
-			for scale in 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8; do
-				scalearg=`echo $scale | sed 's/\_/\//g'`
-				runme $EXEDIR/djpeg -rgb -bmp -scale ${scalearg} -outfile $OUTDIR/${basename}_${samp}_${xform}_${scale}_jpegtran.bmp $OUTDIR/${basename}_${samp}_${xform}_jpegtran.jpg
-				runme "$JAVA" $JAVAARGS TJExample $OUTDIR/${basename}_${samp}_fast.jpg $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp -$xform -scale ${scalearg} -crop 70x60+16+16
-				runme cmp -i 54:54 $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp $OUTDIR/${basename}_${samp}_${xform}_${scale}_jpegtran.bmp
-				rm $OUTDIR/${basename}_${samp}_${xform}_${scale}.bmp
-			done
-		done
-	done
-
-done
-
-echo SUCCESS!
diff --git a/src/third_party/libjpeg-turbo/tjunittest.c b/src/third_party/libjpeg-turbo/tjunittest.c
index 45918a9..af409a5 100644
--- a/src/third_party/libjpeg-turbo/tjunittest.c
+++ b/src/third_party/libjpeg-turbo/tjunittest.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C)2009-2014, 2017-2018 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2009-2014, 2017-2019 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -30,31 +30,24 @@
  * This program tests the various code paths in the TurboJPEG C Wrapper
  */
 
-#ifdef STARBOARD
-#include "starboard/client_porting/poem/stdio_poem.h"
-#else
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#endif
 #include <errno.h>
 #include "tjutil.h"
 #include "turbojpeg.h"
 #include "md5/md5.h"
 #include "cmyk.h"
-
 #ifdef _WIN32
-
-#ifdef STARBOARD
-#include <starboard/time.h>
-#else
 #include <time.h>
 #define random()  rand()
-#endif
+#else
+#include <unistd.h>
 #endif
 
 
-void usage(char *progName)
+#ifndef GTEST
+static void usage(char *progName)
 {
   printf("\nUSAGE: %s [options]\n\n", progName);
   printf("Options:\n");
@@ -65,46 +58,49 @@
   printf("-bmp = tjLoadImage()/tjSaveImage() unit test\n\n");
   exit(1);
 }
+#endif
 
 
-#define _throwtj() { \
-  printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
-  bailout() \
+#define THROW_TJ() { \
+  fprintf(stderr, "TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \
+  BAILOUT() \
 }
-#define _tj(f) { if ((f) == -1) _throwtj(); }
-#define _throw(m) { printf("ERROR: %s\n", m);  bailout() }
-#define _throwmd5(filename, md5sum, ref) { \
-  printf("\n%s has an MD5 sum of %s.\n   Should be %s.\n", filename, md5sum, \
-         ref); \
-  bailout() \
+#define TRY_TJ(f) { if ((f) == -1) THROW_TJ(); }
+#define THROW(m) { printf("ERROR: %s\n", m);  BAILOUT() }
+#define THROW_MD5(filename, md5sum, ref) { \
+  fprintf(stderr, "\n%s has an MD5 sum of %s.\n   Should be %s.\n", filename, \
+          md5sum, ref); \
+  BAILOUT() \
 }
 
-const char *subNameLong[TJ_NUMSAMP] = {
+static const char *subNameLong[TJ_NUMSAMP] = {
   "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1"
 };
-const char *subName[TJ_NUMSAMP] = {
+static const char *subName[TJ_NUMSAMP] = {
   "444", "422", "420", "GRAY", "440", "411"
 };
 
-const char *pixFormatStr[TJ_NUMPF] = {
+static const char *pixFormatStr[TJ_NUMPF] = {
   "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
   "RGBA", "BGRA", "ABGR", "ARGB", "CMYK"
 };
 
-const int _3byteFormats[] = { TJPF_RGB, TJPF_BGR };
-const int _4byteFormats[] = {
+static const int _3byteFormats[] = { TJPF_RGB, TJPF_BGR };
+static const int _4byteFormats[] = {
   TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, TJPF_CMYK
 };
-const int _onlyGray[] = { TJPF_GRAY };
-const int _onlyRGB[] = { TJPF_RGB };
+static const int _onlyGray[] = { TJPF_GRAY };
+static const int _onlyRGB[] = { TJPF_RGB };
 
-int doYUV = 0, alloc = 0, pad = 4;
+static int doYUV = 0, alloc = 0, pad = 4;
 
-int exitStatus = 0;
-#define bailout() { exitStatus = -1;  goto bailout; }
+static int exitStatus = 0;
+#define BAILOUT() { exitStatus = -1;  goto bailout; }
+
+static const size_t filePathSize = 1024;
 
 
-void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
+static void initBuf(unsigned char *buf, int w, int h, int pf, int flags)
 {
   int roffset = tjRedOffset[pf];
   int goffset = tjGreenOffset[pf];
@@ -159,31 +155,33 @@
 }
 
 
-#define checkval(v, cv) { \
+#define CHECKVAL(v, cv) { \
   if (v < cv - 1 || v > cv + 1) { \
-    printf("\nComp. %s at %d,%d should be %d, not %d\n", #v, row, col, cv, \
-           v); \
+    fprintf(stderr, "\nComp. %s at %d,%d should be %d, not %d\n", #v, row, \
+            col, cv, v); \
     retval = 0;  exitStatus = -1;  goto bailout; \
   } \
 }
 
-#define checkval0(v) { \
+#define CHECKVAL0(v) { \
   if (v > 1) { \
-    printf("\nComp. %s at %d,%d should be 0, not %d\n", #v, row, col, v); \
+    fprintf(stderr, "\nComp. %s at %d,%d should be 0, not %d\n", #v, row, \
+            col, v); \
     retval = 0;  exitStatus = -1;  goto bailout; \
   } \
 }
 
-#define checkval255(v) { \
+#define CHECKVAL255(v) { \
   if (v < 254) { \
-    printf("\nComp. %s at %d,%d should be 255, not %d\n", #v, row, col, v); \
+    fprintf(stderr, "\nComp. %s at %d,%d should be 255, not %d\n", #v, row, \
+            col, v); \
     retval = 0;  exitStatus = -1;  goto bailout; \
   } \
 }
 
 
-int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
-             tjscalingfactor sf, int flags)
+static int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
+                    tjscalingfactor sf, int flags)
 {
   int roffset = tjRedOffset[pf];
   int goffset = tjGreenOffset[pf];
@@ -208,13 +206,13 @@
         y = buf[index * ps + 2];
         k = buf[index * ps + 3];
         if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
-          checkval255(c);  checkval255(m);  checkval255(y);
-          if (row < halfway) checkval255(k)
-          else checkval0(k)
+          CHECKVAL255(c);  CHECKVAL255(m);  CHECKVAL255(y);
+          if (row < halfway) CHECKVAL255(k)
+          else CHECKVAL0(k)
         } else {
-          checkval255(c);  checkval0(y);  checkval255(k);
-          if (row < halfway) checkval0(m)
-          else checkval255(m)
+          CHECKVAL255(c);  CHECKVAL0(y);  CHECKVAL255(k);
+          if (row < halfway) CHECKVAL0(m)
+          else CHECKVAL255(m)
         }
       }
     }
@@ -233,26 +231,26 @@
       a = aoffset >= 0 ? buf[index * ps + aoffset] : 0xFF;
       if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
         if (row < halfway) {
-          checkval255(r);  checkval255(g);  checkval255(b);
+          CHECKVAL255(r);  CHECKVAL255(g);  CHECKVAL255(b);
         } else {
-          checkval0(r);  checkval0(g);  checkval0(b);
+          CHECKVAL0(r);  CHECKVAL0(g);  CHECKVAL0(b);
         }
       } else {
         if (subsamp == TJSAMP_GRAY) {
           if (row < halfway) {
-            checkval(r, 76);  checkval(g, 76);  checkval(b, 76);
+            CHECKVAL(r, 76);  CHECKVAL(g, 76);  CHECKVAL(b, 76);
           } else {
-            checkval(r, 226);  checkval(g, 226);  checkval(b, 226);
+            CHECKVAL(r, 226);  CHECKVAL(g, 226);  CHECKVAL(b, 226);
           }
         } else {
           if (row < halfway) {
-            checkval255(r);  checkval0(g);  checkval0(b);
+            CHECKVAL255(r);  CHECKVAL0(g);  CHECKVAL0(b);
           } else {
-            checkval255(r);  checkval255(g);  checkval0(b);
+            CHECKVAL255(r);  CHECKVAL255(g);  CHECKVAL0(b);
           }
         }
       }
-      checkval255(a);
+      CHECKVAL255(a);
     }
   }
 
@@ -261,15 +259,16 @@
     for (row = 0; row < h; row++) {
       for (col = 0; col < w; col++) {
         if (pf == TJPF_CMYK)
-          printf("%.3d/%.3d/%.3d/%.3d ", buf[(row * w + col) * ps],
-                 buf[(row * w + col) * ps + 1], buf[(row * w + col) * ps + 2],
-                 buf[(row * w + col) * ps + 3]);
+          fprintf(stderr, "%.3d/%.3d/%.3d/%.3d ", buf[(row * w + col) * ps],
+                  buf[(row * w + col) * ps + 1], buf[(row * w + col) * ps + 2],
+                  buf[(row * w + col) * ps + 3]);
         else
-          printf("%.3d/%.3d/%.3d ", buf[(row * w + col) * ps + roffset],
-                 buf[(row * w + col) * ps + goffset],
-                 buf[(row * w + col) * ps + boffset]);
+          fprintf(stderr, "%.3d/%.3d/%.3d ",
+                  buf[(row * w + col) * ps + roffset],
+                  buf[(row * w + col) * ps + goffset],
+                  buf[(row * w + col) * ps + boffset]);
       }
-      printf("\n");
+      fprintf(stderr, "\n");
     }
   }
   return retval;
@@ -278,8 +277,8 @@
 
 #define PAD(v, p)  ((v + (p) - 1) & (~((p) - 1)))
 
-int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
-                tjscalingfactor sf)
+static int checkBufYUV(unsigned char *buf, int w, int h, int subsamp,
+                       tjscalingfactor sf)
 {
   int row, col;
   int hsf = tjMCUWidth[subsamp] / 8, vsf = tjMCUHeight[subsamp] / 8;
@@ -295,16 +294,16 @@
       unsigned char y = buf[ypitch * row + col];
 
       if (((row / blocksize) + (col / blocksize)) % 2 == 0) {
-        if (row < halfway) checkval255(y)
-        else checkval0(y);
+        if (row < halfway) CHECKVAL255(y)
+        else CHECKVAL0(y);
       } else {
-        if (row < halfway) checkval(y, 76)
-        else checkval(y, 226);
+        if (row < halfway) CHECKVAL(y, 76)
+        else CHECKVAL(y, 226);
       }
     }
   }
   if (subsamp != TJSAMP_GRAY) {
-    int halfway = 16 / vsf * sf.num / sf.denom;
+    halfway = 16 / vsf * sf.num / sf.denom;
 
     for (row = 0; row < ch; row++) {
       for (col = 0; col < cw; col++) {
@@ -312,12 +311,12 @@
           v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
 
         if (((row * vsf / blocksize) + (col * hsf / blocksize)) % 2 == 0) {
-          checkval(u, 128);  checkval(v, 128);
+          CHECKVAL(u, 128);  CHECKVAL(v, 128);
         } else {
           if (row < halfway) {
-            checkval(u, 85);  checkval255(v);
+            CHECKVAL(u, 85);  CHECKVAL255(v);
           } else {
-            checkval0(u);  checkval(v, 149);
+            CHECKVAL0(u);  CHECKVAL(v, 149);
           }
         }
       }
@@ -328,21 +327,21 @@
   if (retval == 0) {
     for (row = 0; row < ph; row++) {
       for (col = 0; col < pw; col++)
-        printf("%.3d ", buf[ypitch * row + col]);
-      printf("\n");
+        fprintf(stderr, "%.3d ", buf[ypitch * row + col]);
+      fprintf(stderr, "\n");
     }
-    printf("\n");
+    fprintf(stderr, "\n");
     for (row = 0; row < ch; row++) {
       for (col = 0; col < cw; col++)
-        printf("%.3d ", buf[ypitch * ph + (uvpitch * row + col)]);
-      printf("\n");
+        fprintf(stderr, "%.3d ", buf[ypitch * ph + (uvpitch * row + col)]);
+      fprintf(stderr, "\n");
     }
-    printf("\n");
+    fprintf(stderr, "\n");
     for (row = 0; row < ch; row++) {
       for (col = 0; col < cw; col++)
-        printf("%.3d ",
-               buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]);
-      printf("\n");
+        fprintf(stderr, "%.3d ",
+                buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]);
+      fprintf(stderr, "\n");
     }
   }
 
@@ -350,13 +349,20 @@
 }
 
 
-void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize, char *filename)
+static void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize,
+                      char *filename)
 {
+#if defined(ANDROID) && defined(GTEST)
+  char path[filePathSize];
+  snprintf(path, filePathSize, "/sdcard/%s", filename);
+  FILE *file = fopen(path, "wb");
+#else
   FILE *file = fopen(filename, "wb");
-
+#endif
   if (!file || fwrite(jpegBuf, jpegSize, 1, file) != 1) {
-    printf("ERROR: Could not write to %s.\n%s\n", filename, strerror(errno));
-    bailout()
+    fprintf(stderr, "ERROR: Could not write to %s.\n%s\n", filename,
+            strerror(errno));
+    BAILOUT()
   }
 
 bailout:
@@ -364,11 +370,11 @@
 }
 
 
-void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize,
-              int w, int h, int pf, char *basename, int subsamp, int jpegQual,
-              int flags)
+static void compTest(tjhandle handle, unsigned char **dstBuf,
+                     unsigned long *dstSize, int w, int h, int pf,
+                     char *basename, int subsamp, int jpegQual, int flags)
 {
-  char tempStr[1024];
+  char tempStr[filePathSize];
   unsigned char *srcBuf = NULL, *yuvBuf = NULL;
   const char *pfStr = pixFormatStr[pf];
   const char *buStrLong =
@@ -376,7 +382,7 @@
   const char *buStr = (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD";
 
   if ((srcBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL)
-    _throw("Memory allocation failure");
+    THROW("Memory allocation failure");
   initBuf(srcBuf, w, h, pf, flags);
 
   if (*dstBuf && *dstSize > 0) memset(*dstBuf, 0, *dstSize);
@@ -387,44 +393,46 @@
     tjscalingfactor sf = { 1, 1 };
     tjhandle handle2 = tjInitCompress();
 
-    if (!handle2) _throwtj();
+    if (!handle2) THROW_TJ();
 
     if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
-      _throw("Memory allocation failure");
+      THROW("Memory allocation failure");
     memset(yuvBuf, 0, yuvSize);
 
-    printf("%s %s -> YUV %s ... ", pfStr, buStrLong, subNameLong[subsamp]);
-    _tj(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp,
-                     flags));
+    fprintf(stderr, "%s %s -> YUV %s ... ", pfStr, buStrLong,
+            subNameLong[subsamp]);
+    TRY_TJ(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp,
+                        flags));
     tjDestroy(handle2);
-    if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) printf("Passed.\n");
-    else printf("FAILED!\n");
+    if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) fprintf(stderr, "Passed.\n");
+    else fprintf(stderr, "FAILED!\n");
 
-    printf("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp], buStrLong,
-           jpegQual);
-    _tj(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf, dstSize,
-                          jpegQual, flags));
+    fprintf(stderr, "YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp],
+            buStrLong, jpegQual);
+    TRY_TJ(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf,
+                             dstSize, jpegQual, flags));
   } else {
-    printf("%s %s -> %s Q%d ... ", pfStr, buStrLong, subNameLong[subsamp],
-           jpegQual);
-    _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
-                    jpegQual, flags));
+    fprintf(stderr, "%s %s -> %s Q%d ... ", pfStr, buStrLong,
+            subNameLong[subsamp], jpegQual);
+    TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp,
+                       jpegQual, flags));
   }
 
-  snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr, buStr,
-           subName[subsamp], jpegQual);
+  snprintf(tempStr, filePathSize, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr,
+           buStr, subName[subsamp], jpegQual);
   writeJPEG(*dstBuf, *dstSize, tempStr);
-  printf("Done.\n  Result in %s\n", tempStr);
+  fprintf(stderr, "Done.\n  Result in %s\n", tempStr);
 
 bailout:
-  if (yuvBuf) free(yuvBuf);
-  if (srcBuf) free(srcBuf);
+  free(yuvBuf);
+  free(srcBuf);
 }
 
 
-void _decompTest(tjhandle handle, unsigned char *jpegBuf,
-                 unsigned long jpegSize, int w, int h, int pf, char *basename,
-                 int subsamp, int flags, tjscalingfactor sf)
+static void _decompTest(tjhandle handle, unsigned char *jpegBuf,
+                        unsigned long jpegSize, int w, int h, int pf,
+                        char *basename, int subsamp, int flags,
+                        tjscalingfactor sf)
 {
   unsigned char *dstBuf = NULL, *yuvBuf = NULL;
   int _hdrw = 0, _hdrh = 0, _hdrsubsamp = -1;
@@ -432,14 +440,14 @@
   int scaledHeight = TJSCALED(h, sf);
   unsigned long dstSize = 0;
 
-  _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
-                          &_hdrsubsamp));
+  TRY_TJ(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh,
+                             &_hdrsubsamp));
   if (_hdrw != w || _hdrh != h || _hdrsubsamp != subsamp)
-    _throw("Incorrect JPEG header");
+    THROW("Incorrect JPEG header");
 
   dstSize = scaledWidth * scaledHeight * tjPixelSize[pf];
   if ((dstBuf = (unsigned char *)malloc(dstSize)) == NULL)
-    _throw("Memory allocation failure");
+    THROW("Memory allocation failure");
   memset(dstBuf, 0, dstSize);
 
   if (doYUV) {
@@ -447,56 +455,57 @@
                                           subsamp);
     tjhandle handle2 = tjInitDecompress();
 
-    if (!handle2) _throwtj();
+    if (!handle2) THROW_TJ();
 
     if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL)
-      _throw("Memory allocation failure");
+      THROW("Memory allocation failure");
     memset(yuvBuf, 0, yuvSize);
 
-    printf("JPEG -> YUV %s ", subNameLong[subsamp]);
+    fprintf(stderr, "JPEG -> YUV %s ", subNameLong[subsamp]);
     if (sf.num != 1 || sf.denom != 1)
-      printf("%d/%d ... ", sf.num, sf.denom);
-    else printf("... ");
-    _tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth, pad,
-                           scaledHeight, flags));
+      fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
+    else fprintf(stderr, "... ");
+    TRY_TJ(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth,
+                              pad, scaledHeight, flags));
     if (checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf))
-      printf("Passed.\n");
-    else printf("FAILED!\n");
+      fprintf(stderr, "Passed.\n");
+    else fprintf(stderr, "FAILED!\n");
 
-    printf("YUV %s -> %s %s ... ", subNameLong[subsamp], pixFormatStr[pf],
-           (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
-    _tj(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0,
-                    scaledHeight, pf, flags));
+    fprintf(stderr, "YUV %s -> %s %s ... ", subNameLong[subsamp],
+            pixFormatStr[pf],
+            (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
+    TRY_TJ(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0,
+                       scaledHeight, pf, flags));
     tjDestroy(handle2);
   } else {
-    printf("JPEG -> %s %s ", pixFormatStr[pf],
-           (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
+    fprintf(stderr, "JPEG -> %s %s ", pixFormatStr[pf],
+            (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down ");
     if (sf.num != 1 || sf.denom != 1)
-      printf("%d/%d ... ", sf.num, sf.denom);
-    else printf("... ");
-    _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0,
-                      scaledHeight, pf, flags));
+      fprintf(stderr, "%d/%d ... ", sf.num, sf.denom);
+    else fprintf(stderr, "... ");
+    TRY_TJ(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0,
+                         scaledHeight, pf, flags));
   }
 
   if (checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags))
-    printf("Passed.");
-  else printf("FAILED!");
-  printf("\n");
+    fprintf(stderr, "Passed.");
+  else fprintf(stderr, "FAILED!");
+  fprintf(stderr, "\n");
 
 bailout:
-  if (yuvBuf) free(yuvBuf);
-  if (dstBuf) free(dstBuf);
+  free(yuvBuf);
+  free(dstBuf);
 }
 
 
-void decompTest(tjhandle handle, unsigned char *jpegBuf,
-                unsigned long jpegSize, int w, int h, int pf, char *basename,
-                int subsamp, int flags)
+static void decompTest(tjhandle handle, unsigned char *jpegBuf,
+                       unsigned long jpegSize, int w, int h, int pf,
+                       char *basename, int subsamp, int flags)
 {
   int i, n = 0;
   tjscalingfactor *sf = tjGetScalingFactors(&n);
 
-  if (!sf || !n) _throwtj();
+  if (!sf || !n) THROW_TJ();
 
   for (i = 0; i < n; i++) {
     if (subsamp == TJSAMP_444 || subsamp == TJSAMP_GRAY ||
@@ -513,8 +522,8 @@
 }
 
 
-void doTest(int w, int h, const int *formats, int nformats, int subsamp,
-            char *basename)
+static void doTest(int w, int h, const int *formats, int nformats, int subsamp,
+                   char *basename)
 {
   tjhandle chandle = NULL, dhandle = NULL;
   unsigned char *dstBuf = NULL;
@@ -525,11 +534,11 @@
     size = tjBufSize(w, h, subsamp);
   if (size != 0)
     if ((dstBuf = (unsigned char *)tjAlloc(size)) == NULL)
-      _throw("Memory allocation failure.");
+      THROW("Memory allocation failure.");
 
   if ((chandle = tjInitCompress()) == NULL ||
       (dhandle = tjInitDecompress()) == NULL)
-    _throwtj();
+    THROW_TJ();
 
   for (pfi = 0; pfi < nformats; pfi++) {
     for (i = 0; i < 2; i++) {
@@ -544,45 +553,84 @@
                flags);
       decompTest(dhandle, dstBuf, size, w, h, pf, basename, subsamp, flags);
       if (pf >= TJPF_RGBX && pf <= TJPF_XRGB) {
-        printf("\n");
+        fprintf(stderr, "\n");
         decompTest(dhandle, dstBuf, size, w, h, pf + (TJPF_RGBA - TJPF_RGBX),
                    basename, subsamp, flags);
       }
-      printf("\n");
+      fprintf(stderr, "\n");
     }
   }
-  printf("--------------------\n\n");
+  fprintf(stderr, "--------------------\n\n");
 
 bailout:
   if (chandle) tjDestroy(chandle);
   if (dhandle) tjDestroy(dhandle);
-  if (dstBuf) tjFree(dstBuf);
+  tjFree(dstBuf);
 }
 
 
-void bufSizeTest(void)
+#if SIZEOF_SIZE_T == 8
+#define CHECKSIZE(function) { \
+  if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \
+    THROW(#function " overflow"); \
+}
+#else
+#define CHECKSIZE(function) { \
+  if (size != (unsigned long)(-1) || \
+      !strcmp(tjGetErrorStr2(NULL), "No error")) \
+    THROW(#function " overflow"); \
+}
+#endif
+
+#ifndef GTEST
+static void overflowTest(void)
+{
+  /* Ensure that the various buffer size functions don't overflow */
+  unsigned long size;
+
+  size = tjBufSize(26755, 26755, TJSAMP_444);
+  CHECKSIZE(tjBufSize());
+  size = TJBUFSIZE(26755, 26755);
+  CHECKSIZE(TJBUFSIZE());
+  size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444);
+  CHECKSIZE(tjBufSizeYUV2());
+  size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444);
+  CHECKSIZE(TJBUFSIZEYUV());
+  size = tjBufSizeYUV(37838, 37838, TJSAMP_444);
+  CHECKSIZE(tjBufSizeYUV());
+  size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444);
+  CHECKSIZE(tjPlaneSizeYUV());
+
+bailout:
+  return;
+}
+#endif
+
+
+static void bufSizeTest(void)
 {
   int w, h, i, subsamp;
   unsigned char *srcBuf = NULL, *dstBuf = NULL;
   tjhandle handle = NULL;
   unsigned long dstSize = 0;
 
-  if ((handle = tjInitCompress()) == NULL) _throwtj();
+  if ((handle = tjInitCompress()) == NULL) THROW_TJ();
 
-  printf("Buffer size regression test\n");
+  fprintf(stderr, "Buffer size regression test\n");
   for (subsamp = 0; subsamp < TJ_NUMSAMP; subsamp++) {
     for (w = 1; w < 48; w++) {
       int maxh = (w == 1) ? 2048 : 48;
 
       for (h = 1; h < maxh; h++) {
-        if (h % 100 == 0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
+        if (h % 100 == 0)
+          fprintf(stderr, "%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h);
         if ((srcBuf = (unsigned char *)malloc(w * h * 4)) == NULL)
-          _throw("Memory allocation failure");
+          THROW("Memory allocation failure");
         if (!alloc || doYUV) {
           if (doYUV) dstSize = tjBufSizeYUV2(w, pad, h, subsamp);
           else dstSize = tjBufSize(w, h, subsamp);
           if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
-            _throw("Memory allocation failure");
+            THROW("Memory allocation failure");
         }
 
         for (i = 0; i < w * h * 4; i++) {
@@ -591,12 +639,12 @@
         }
 
         if (doYUV) {
-          _tj(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad,
-                           subsamp, 0));
+          TRY_TJ(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad,
+                              subsamp, 0));
         } else {
-          _tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
-                          &dstSize, subsamp, 100,
-                          alloc ? 0 : TJFLAG_NOREALLOC));
+          TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf,
+                             &dstSize, subsamp, 100,
+                             alloc ? 0 : TJFLAG_NOREALLOC));
         }
         free(srcBuf);  srcBuf = NULL;
         if (!alloc || doYUV) {
@@ -604,12 +652,12 @@
         }
 
         if ((srcBuf = (unsigned char *)malloc(h * w * 4)) == NULL)
-          _throw("Memory allocation failure");
+          THROW("Memory allocation failure");
         if (!alloc || doYUV) {
           if (doYUV) dstSize = tjBufSizeYUV2(h, pad, w, subsamp);
           else dstSize = tjBufSize(h, w, subsamp);
           if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL)
-            _throw("Memory allocation failure");
+            THROW("Memory allocation failure");
         }
 
         for (i = 0; i < h * w * 4; i++) {
@@ -618,12 +666,12 @@
         }
 
         if (doYUV) {
-          _tj(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad,
-                           subsamp, 0));
+          TRY_TJ(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad,
+                              subsamp, 0));
         } else {
-          _tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
-                          &dstSize, subsamp, 100,
-                          alloc ? 0 : TJFLAG_NOREALLOC));
+          TRY_TJ(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf,
+                             &dstSize, subsamp, 100,
+                             alloc ? 0 : TJFLAG_NOREALLOC));
         }
         free(srcBuf);  srcBuf = NULL;
         if (!alloc || doYUV) {
@@ -632,17 +680,17 @@
       }
     }
   }
-  printf("Done.      \n");
+  fprintf(stderr, "Done.      \n");
 
 bailout:
-  if (srcBuf) free(srcBuf);
-  if (dstBuf) tjFree(dstBuf);
+  free(srcBuf);
+  tjFree(dstBuf);
   if (handle) tjDestroy(handle);
 }
 
 
-void initBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
-                int flags)
+static void initBitmap(unsigned char *buf, int width, int pitch, int height,
+                       int pf, int flags)
 {
   int roffset = tjRedOffset[pf];
   int goffset = tjGreenOffset[pf];
@@ -675,8 +723,8 @@
 }
 
 
-int cmpBitmap(unsigned char *buf, int width, int pitch, int height, int pf,
-              int flags, int gray2rgb)
+static int cmpBitmap(unsigned char *buf, int width, int pitch, int height,
+                     int pf, int flags, int gray2rgb)
 {
   int roffset = tjRedOffset[pf];
   int goffset = tjGreenOffset[pf];
@@ -726,10 +774,11 @@
 }
 
 
-int doBmpTest(const char *ext, int width, int align, int height, int pf,
-              int flags)
+static int doBmpTest(const char *ext, int width, int align, int height, int pf,
+                     int flags)
 {
-  char filename[80], *md5sum, md5buf[65];
+  const size_t filenameSize = 80;
+  char filename[filenameSize], *md5sum, md5buf[65];
   int ps = tjPixelSize[pf], pitch = PAD(width * ps, align), loadWidth = 0,
     loadHeight = 0, retval = 0, pixelFormat = pf;
   unsigned char *buf = NULL;
@@ -744,26 +793,32 @@
   }
 
   if ((buf = (unsigned char *)tjAlloc(pitch * height)) == NULL)
-    _throw("Could not allocate memory");
+    THROW("Could not allocate memory");
   initBitmap(buf, width, pitch, height, pf, flags);
 
-  snprintf(filename, 80, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf], align,
-           (flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext);
-  _tj(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
+#if defined(ANDROID) && defined(GTEST)
+  snprintf(filename, filenameSize, "/sdcard/test_bmp_%s_%d_%s.%s",
+           pixFormatStr[pf], align, (flags & TJFLAG_BOTTOMUP) ? "bu" : "td",
+           ext);
+#else
+  snprintf(filename, filenameSize, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf],
+           align, (flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext);
+#endif
+  TRY_TJ(tjSaveImage(filename, buf, width, pitch, height, pf, flags));
   md5sum = MD5File(filename, md5buf);
   if (strcasecmp(md5sum, md5ref))
-    _throwmd5(filename, md5sum, md5ref);
+    THROW_MD5(filename, md5sum, md5ref);
 
   tjFree(buf);  buf = NULL;
   if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
                          flags)) == NULL)
-    _throwtj();
+    THROW_TJ();
   if (width != loadWidth || height != loadHeight) {
-    printf("\n   Image dimensions of %s are bogus\n", filename);
+    fprintf(stderr, "\n   Image dimensions of %s are bogus\n", filename);
     retval = -1;  goto bailout;
   }
   if (!cmpBitmap(buf, width, pitch, height, pf, flags, 0)) {
-    printf("\n   Pixel data in %s is bogus\n", filename);
+    fprintf(stderr, "\n   Pixel data in %s is bogus\n", filename);
     retval = -1;  goto bailout;
   }
   if (pf == TJPF_GRAY) {
@@ -771,10 +826,10 @@
     pf = TJPF_XBGR;
     if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
                            flags)) == NULL)
-      _throwtj();
+      THROW_TJ();
     pitch = PAD(width * tjPixelSize[pf], align);
     if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
-      printf("\n   Converting %s to RGB failed\n", filename);
+      fprintf(stderr, "\n   Converting %s to RGB failed\n", filename);
       retval = -1;  goto bailout;
     }
 
@@ -782,10 +837,10 @@
     pf = TJPF_CMYK;
     if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf,
                            flags)) == NULL)
-      _throwtj();
+      THROW_TJ();
     pitch = PAD(width * tjPixelSize[pf], align);
     if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) {
-      printf("\n   Converting %s to CMYK failed\n", filename);
+      fprintf(stderr, "\n   Converting %s to CMYK failed\n", filename);
       retval = -1;  goto bailout;
     }
   }
@@ -796,56 +851,57 @@
   pixelFormat = TJPF_UNKNOWN;
   if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight,
                          &pixelFormat, flags)) == NULL)
-    _throwtj();
+    THROW_TJ();
   if ((pf == TJPF_GRAY && pixelFormat != TJPF_GRAY) ||
       (pf != TJPF_GRAY && !strcasecmp(ext, "bmp") &&
        pixelFormat != TJPF_BGR) ||
       (pf != TJPF_GRAY && !strcasecmp(ext, "ppm") &&
        pixelFormat != TJPF_RGB)) {
-    printf("\n   tjLoadImage() returned unexpected pixel format: %s\n",
-           pixFormatStr[pixelFormat]);
+    fprintf(stderr,
+            "\n   tjLoadImage() returned unexpected pixel format: %s\n",
+            pixFormatStr[pixelFormat]);
     retval = -1;
   }
   unlink(filename);
 
 bailout:
-  if (buf) tjFree(buf);
+  tjFree(buf);
   if (exitStatus < 0) return exitStatus;
   return retval;
 }
 
 
-int bmpTest(void)
+static int bmpTest(void)
 {
   int align, width = 35, height = 39, format;
 
   for (align = 1; align <= 8; align *= 2) {
     for (format = 0; format < TJ_NUMPF; format++) {
-      printf("%s Top-Down BMP (row alignment = %d bytes)  ...  ",
-             pixFormatStr[format], align);
+      fprintf(stderr, "%s Top-Down BMP (row alignment = %d bytes)  ...  ",
+              pixFormatStr[format], align);
       if (doBmpTest("bmp", width, align, height, format, 0) == -1)
         return -1;
-      printf("OK.\n");
+      fprintf(stderr, "OK.\n");
 
-      printf("%s Top-Down PPM (row alignment = %d bytes)  ...  ",
-             pixFormatStr[format], align);
+      fprintf(stderr, "%s Top-Down PPM (row alignment = %d bytes)  ...  ",
+              pixFormatStr[format], align);
       if (doBmpTest("ppm", width, align, height, format,
                     TJFLAG_BOTTOMUP) == -1)
         return -1;
-      printf("OK.\n");
+      fprintf(stderr, "OK.\n");
 
-      printf("%s Bottom-Up BMP (row alignment = %d bytes)  ...  ",
-             pixFormatStr[format], align);
+      fprintf(stderr, "%s Bottom-Up BMP (row alignment = %d bytes)  ...  ",
+              pixFormatStr[format], align);
       if (doBmpTest("bmp", width, align, height, format, 0) == -1)
         return -1;
-      printf("OK.\n");
+      fprintf(stderr, "OK.\n");
 
-      printf("%s Bottom-Up PPM (row alignment = %d bytes)  ...  ",
-             pixFormatStr[format], align);
+      fprintf(stderr, "%s Bottom-Up PPM (row alignment = %d bytes)  ...  ",
+              pixFormatStr[format], align);
       if (doBmpTest("ppm", width, align, height, format,
                     TJFLAG_BOTTOMUP) == -1)
         return -1;
-      printf("OK.\n");
+      fprintf(stderr, "OK.\n");
     }
   }
 
@@ -853,6 +909,220 @@
 }
 
 
+#ifdef GTEST
+static void initTJUnitTest(int yuv, int noyuvpad, int autoalloc)
+{
+  doYUV = yuv ? 1 : 0;
+  pad = noyuvpad ? 1 : 4;
+  alloc = autoalloc ? 1 : 0;
+
+  exitStatus = 0;
+}
+
+
+int testBmp(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  return bmpTest();
+}
+
+
+int testThreeByte444(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
+  return exitStatus;
+}
+
+
+int testFourByte444(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  int num4bf = doYUV ? 4 : 5;
+  doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
+  return exitStatus;
+}
+
+
+int testThreeByte422(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
+  return exitStatus;
+}
+
+
+int testFourByte422(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  int num4bf = doYUV ? 4 : 5;
+  doTest(35, 39, _4byteFormats, num4bf, TJSAMP_422, "test");
+  return exitStatus;
+}
+
+
+int testThreeByte420(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(39, 41, _3byteFormats, 2, TJSAMP_420, "test");
+  return exitStatus;
+}
+
+
+int testFourByte420(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  int num4bf = doYUV ? 4 : 5;
+  doTest(41, 35, _4byteFormats, num4bf, TJSAMP_420, "test");
+  return exitStatus;
+}
+
+
+int testThreeByte440(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(35, 39, _3byteFormats, 2, TJSAMP_440, "test");
+  return exitStatus;
+}
+
+
+int testFourByte440(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  int num4bf = doYUV ? 4 : 5;
+  doTest(39, 41, _4byteFormats, num4bf, TJSAMP_440, "test");
+  return exitStatus;
+}
+
+
+int testThreeByte411(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(41, 35, _3byteFormats, 2, TJSAMP_411, "test");
+  return exitStatus;
+}
+
+
+int testFourByte411(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  int num4bf = doYUV ? 4 : 5;
+  doTest(35, 39, _4byteFormats, num4bf, TJSAMP_411, "test");
+  return exitStatus;
+}
+
+
+int testOnlyGray(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(39, 41, _onlyGray, 1, TJSAMP_GRAY, "test");
+  return exitStatus;
+}
+
+
+int testThreeByteGray(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(41, 35, _3byteFormats, 2, TJSAMP_GRAY, "test");
+  return exitStatus;
+}
+
+
+int testFourByteGray(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  doTest(35, 39, _4byteFormats, 4, TJSAMP_GRAY, "test");
+  return exitStatus;
+}
+
+
+int testBufSize(int yuv, int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(yuv, noyuvpad, autoalloc);
+
+  bufSizeTest();
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGB444(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_444, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGB422(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_422, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGB420(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_420, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGB440(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_440, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGB411(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_411, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyRGBGray(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyRGB, 1, TJSAMP_GRAY, "test_yuv0");
+  return exitStatus;
+}
+
+
+int testYUVOnlyGrayGray(int noyuvpad, int autoalloc)
+{
+  initTJUnitTest(1, noyuvpad, autoalloc);
+
+  doTest(48, 48, _onlyGray, 1, TJSAMP_GRAY, "test_yuv0");
+  return exitStatus;
+}
+
+#else
+
 int main(int argc, char *argv[])
 {
   int i, num4bf = 5;
@@ -871,6 +1141,7 @@
   }
   if (alloc) printf("Testing automatic buffer allocation\n");
   if (doYUV) num4bf = 4;
+  overflowTest();
   doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test");
   doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test");
   doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test");
@@ -898,3 +1169,4 @@
 
   return exitStatus;
 }
+#endif
diff --git a/src/third_party/libjpeg-turbo/tjutil.c b/src/third_party/libjpeg-turbo/tjutil.c
index b44086d..2018160 100644
--- a/src/third_party/libjpeg-turbo/tjutil.c
+++ b/src/third_party/libjpeg-turbo/tjutil.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C)2011 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2011, 2019 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -29,6 +29,7 @@
 #ifdef _WIN32
 
 #include <windows.h>
+#include "tjutil.h"
 
 static double getFreq(void)
 {
@@ -56,6 +57,7 @@
 
 #include <stdlib.h>
 #include <sys/time.h>
+#include "tjutil.h"
 
 double getTime(void)
 {
diff --git a/src/third_party/libjpeg-turbo/tjutil.h b/src/third_party/libjpeg-turbo/tjutil.h
index 2485016..34a9e37 100644
--- a/src/third_party/libjpeg-turbo/tjutil.h
+++ b/src/third_party/libjpeg-turbo/tjutil.h
@@ -34,7 +34,7 @@
 #else
 #include <stdio.h>
 #define snprintf(str, n, format, ...) \
-  _snprintf_s(str, n, _TRUNCATE, format, __VA_ARGS__)
+  _snprintf_s(str, n, _TRUNCATE, format, ##__VA_ARGS__)
 #endif
 
 #endif
diff --git a/src/third_party/libjpeg-turbo/transupp.c b/src/third_party/libjpeg-turbo/transupp.c
index f3370ac..6e86077 100644
--- a/src/third_party/libjpeg-turbo/transupp.c
+++ b/src/third_party/libjpeg-turbo/transupp.c
@@ -2,7 +2,7 @@
  * transupp.c
  *
  * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2010, 2017, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
@@ -89,6 +89,189 @@
 
 
 LOCAL(void)
+dequant_comp(j_decompress_ptr cinfo, jpeg_component_info *compptr,
+             jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
+{
+  JDIMENSION blk_x, blk_y;
+  int offset_y, k;
+  JQUANT_TBL *qtblptr;
+  JBLOCKARRAY buffer;
+  JBLOCKROW block;
+  JCOEFPTR ptr;
+
+  qtblptr = compptr->quant_table;
+  for (blk_y = 0; blk_y < compptr->height_in_blocks;
+       blk_y += compptr->v_samp_factor) {
+    buffer = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr)cinfo, coef_array, blk_y,
+       (JDIMENSION)compptr->v_samp_factor, TRUE);
+    for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+      block = buffer[offset_y];
+      for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
+        ptr = block[blk_x];
+        for (k = 0; k < DCTSIZE2; k++)
+          if (qtblptr->quantval[k] != qtblptr1->quantval[k])
+            ptr[k] *= qtblptr->quantval[k] / qtblptr1->quantval[k];
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+requant_comp(j_decompress_ptr cinfo, jpeg_component_info *compptr,
+             jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
+{
+  JDIMENSION blk_x, blk_y;
+  int offset_y, k;
+  JQUANT_TBL *qtblptr;
+  JBLOCKARRAY buffer;
+  JBLOCKROW block;
+  JCOEFPTR ptr;
+  JCOEF temp, qval;
+
+  qtblptr = compptr->quant_table;
+  for (blk_y = 0; blk_y < compptr->height_in_blocks;
+       blk_y += compptr->v_samp_factor) {
+    buffer = (*cinfo->mem->access_virt_barray)
+      ((j_common_ptr)cinfo, coef_array, blk_y,
+       (JDIMENSION)compptr->v_samp_factor, TRUE);
+    for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+      block = buffer[offset_y];
+      for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
+        ptr = block[blk_x];
+        for (k = 0; k < DCTSIZE2; k++) {
+          temp = qtblptr->quantval[k];
+          qval = qtblptr1->quantval[k];
+          if (temp != qval) {
+            temp *= ptr[k];
+            /* The following quantization code is copied from jcdctmgr.c */
+#ifdef FAST_DIVIDE
+#define DIVIDE_BY(a, b)  a /= b
+#else
+#define DIVIDE_BY(a, b)  if (a >= b) a /= b;  else a = 0
+#endif
+            if (temp < 0) {
+              temp = -temp;
+              temp += qval >> 1; /* for rounding */
+              DIVIDE_BY(temp, qval);
+              temp = -temp;
+            } else {
+              temp += qval >> 1; /* for rounding */
+              DIVIDE_BY(temp, qval);
+            }
+            ptr[k] = temp;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+/*
+ * Calculate largest common denominator using Euclid's algorithm.
+ */
+LOCAL(JCOEF)
+largest_common_denominator(JCOEF a, JCOEF b)
+{
+  JCOEF c;
+
+  do {
+    c = a % b;
+    a = b;
+    b = c;
+  } while (c);
+
+  return a;
+}
+
+
+LOCAL(void)
+adjust_quant(j_decompress_ptr srcinfo, jvirt_barray_ptr *src_coef_arrays,
+             j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
+             boolean trim, j_compress_ptr dstinfo)
+{
+  jpeg_component_info *compptr1, *compptr2;
+  JQUANT_TBL *qtblptr1, *qtblptr2, *qtblptr3;
+  int ci, k;
+
+  for (ci = 0; ci < dstinfo->num_components && ci < dropinfo->num_components;
+       ci++) {
+    compptr1 = srcinfo->comp_info + ci;
+    compptr2 = dropinfo->comp_info + ci;
+    qtblptr1 = compptr1->quant_table;
+    qtblptr2 = compptr2->quant_table;
+    for (k = 0; k < DCTSIZE2; k++) {
+      if (qtblptr1->quantval[k] != qtblptr2->quantval[k]) {
+        if (trim)
+          requant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr1);
+        else {
+          qtblptr3 = dstinfo->quant_tbl_ptrs[compptr1->quant_tbl_no];
+          for (k = 0; k < DCTSIZE2; k++)
+            if (qtblptr1->quantval[k] != qtblptr2->quantval[k])
+              qtblptr3->quantval[k] =
+                largest_common_denominator(qtblptr1->quantval[k],
+                                           qtblptr2->quantval[k]);
+          dequant_comp(srcinfo, compptr1, src_coef_arrays[ci], qtblptr3);
+          dequant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr3);
+        }
+        break;
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_drop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+        JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+        jvirt_barray_ptr *src_coef_arrays,
+        j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
+        JDIMENSION drop_width, JDIMENSION drop_height)
+/* Drop (insert) the contents of another image into the source image.  If the
+ * number of components in the drop image is smaller than the number of
+ * components in the destination image, then we fill in the remaining
+ * components with zero.  This allows for dropping the contents of grayscale
+ * images into (arbitrarily sampled) color images.
+ */
+{
+  JDIMENSION comp_width, comp_height;
+  JDIMENSION blk_y, x_drop_blocks, y_drop_blocks;
+  int ci, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  jpeg_component_info *compptr;
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = drop_width * compptr->h_samp_factor;
+    comp_height = drop_height * compptr->v_samp_factor;
+    x_drop_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_drop_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (blk_y = 0; blk_y < comp_height; blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], blk_y + y_drop_blocks,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      if (ci < dropinfo->num_components) {
+        src_buffer = (*dropinfo->mem->access_virt_barray)
+          ((j_common_ptr)dropinfo, drop_coef_arrays[ci], blk_y,
+           (JDIMENSION)compptr->v_samp_factor, FALSE);
+        for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+          jcopy_block_row(src_buffer[offset_y],
+                          dst_buffer[offset_y] + x_drop_blocks, comp_width);
+        }
+      } else {
+        for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+          MEMZERO(dst_buffer[offset_y] + x_drop_blocks,
+                  comp_width * sizeof(JBLOCK));
+        }
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
 do_crop(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
         JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
         jvirt_barray_ptr *src_coef_arrays,
@@ -113,13 +296,422 @@
         ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
          (JDIMENSION)compptr->v_samp_factor, TRUE);
       src_buffer = (*srcinfo->mem->access_virt_barray)
-        ((j_common_ptr)srcinfo, src_coef_arrays[ci],
-         dst_blk_y + y_crop_blocks,
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], dst_blk_y + y_crop_blocks,
          (JDIMENSION)compptr->v_samp_factor, FALSE);
       for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
         jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
-                        dst_buffer[offset_y],
-                        compptr->width_in_blocks);
+                        dst_buffer[offset_y], compptr->width_in_blocks);
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_crop_ext_zero(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+                 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+                 jvirt_barray_ptr *src_coef_arrays,
+                 jvirt_barray_ptr *dst_coef_arrays)
+/* Crop.  This is only used when no rotate/flip is requested with the crop.
+ * Extension: If the destination size is larger than the source, we fill in the
+ * expanded region with zero (neutral gray).  Note that we also have to zero
+ * partial iMCUs at the right and bottom edge of the source image area in this
+ * case.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
+  JDIMENSION dst_blk_y, x_crop_blocks, y_crop_blocks;
+  int ci, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  jpeg_component_info *compptr;
+
+  MCU_cols = srcinfo->output_width /
+             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
+  MCU_rows = srcinfo->output_height /
+             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+         dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      if (dstinfo->_jpeg_height > srcinfo->output_height) {
+        if (dst_blk_y < y_crop_blocks ||
+            dst_blk_y >= y_crop_blocks + comp_height) {
+          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+            MEMZERO(dst_buffer[offset_y],
+                    compptr->width_in_blocks * sizeof(JBLOCK));
+          }
+          continue;
+        }
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+           FALSE);
+      } else {
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+           FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        if (dstinfo->_jpeg_width > srcinfo->output_width) {
+          if (x_crop_blocks > 0) {
+            MEMZERO(dst_buffer[offset_y], x_crop_blocks * sizeof(JBLOCK));
+          }
+          jcopy_block_row(src_buffer[offset_y],
+                          dst_buffer[offset_y] + x_crop_blocks, comp_width);
+          if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
+            MEMZERO(dst_buffer[offset_y] + x_crop_blocks + comp_width,
+                    (compptr->width_in_blocks - x_crop_blocks - comp_width) *
+                    sizeof(JBLOCK));
+          }
+        } else {
+          jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
+                          dst_buffer[offset_y], compptr->width_in_blocks);
+        }
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_crop_ext_flat(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+                 JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+                 jvirt_barray_ptr *src_coef_arrays,
+                 jvirt_barray_ptr *dst_coef_arrays)
+/* Crop.  This is only used when no rotate/flip is requested with the crop.
+ * Extension: The destination width is larger than the source, and we fill in
+ * the expanded region with the DC coefficient of the adjacent block.  Note
+ * that we also have to fill partial iMCUs at the right and bottom edge of the
+ * source image area in this case.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
+  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
+  int ci, offset_y;
+  JCOEF dc;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  jpeg_component_info *compptr;
+
+  MCU_cols = srcinfo->output_width /
+             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
+  MCU_rows = srcinfo->output_height /
+             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+         dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      if (dstinfo->_jpeg_height > srcinfo->output_height) {
+        if (dst_blk_y < y_crop_blocks ||
+            dst_blk_y >= y_crop_blocks + comp_height) {
+          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+            MEMZERO(dst_buffer[offset_y],
+                    compptr->width_in_blocks * sizeof(JBLOCK));
+          }
+          continue;
+        }
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+           FALSE);
+      } else {
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+          FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        if (x_crop_blocks > 0) {
+          MEMZERO(dst_buffer[offset_y], x_crop_blocks * sizeof(JBLOCK));
+          dc = src_buffer[offset_y][0][0];
+          for (dst_blk_x = 0; dst_blk_x < x_crop_blocks; dst_blk_x++) {
+            dst_buffer[offset_y][dst_blk_x][0] = dc;
+          }
+        }
+        jcopy_block_row(src_buffer[offset_y],
+                        dst_buffer[offset_y] + x_crop_blocks, comp_width);
+        if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
+          MEMZERO(dst_buffer[offset_y] + x_crop_blocks + comp_width,
+                  (compptr->width_in_blocks - x_crop_blocks - comp_width) *
+                  sizeof(JBLOCK));
+          dc = src_buffer[offset_y][comp_width - 1][0];
+          for (dst_blk_x = x_crop_blocks + comp_width;
+               dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
+            dst_buffer[offset_y][dst_blk_x][0] = dc;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_crop_ext_reflect(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+                    JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+                    jvirt_barray_ptr *src_coef_arrays,
+                    jvirt_barray_ptr *dst_coef_arrays)
+/* Crop.  This is only used when no rotate/flip is requested with the crop.
+ * Extension: The destination width is larger than the source, and we fill in
+ * the expanded region with repeated reflections of the source image.  Note
+ * that we also have to fill partial iMCUs at the right and bottom edge of the
+ * source image area in this case.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, src_blk_x;
+  JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
+  int ci, k, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JBLOCKROW src_row_ptr, dst_row_ptr;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  MCU_cols = srcinfo->output_width /
+             (dstinfo->max_h_samp_factor * dstinfo_min_DCT_h_scaled_size);
+  MCU_rows = srcinfo->output_height /
+             (dstinfo->max_v_samp_factor * dstinfo_min_DCT_v_scaled_size);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
+    y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+         dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      if (dstinfo->_jpeg_height > srcinfo->output_height) {
+        if (dst_blk_y < y_crop_blocks ||
+            dst_blk_y >= y_crop_blocks + comp_height) {
+          for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+            MEMZERO(dst_buffer[offset_y],
+                    compptr->width_in_blocks * sizeof(JBLOCK));
+          }
+          continue;
+        }
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y - y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+           FALSE);
+      } else {
+        src_buffer = (*srcinfo->mem->access_virt_barray)
+          ((j_common_ptr)srcinfo, src_coef_arrays[ci],
+           dst_blk_y + y_crop_blocks, (JDIMENSION)compptr->v_samp_factor,
+           FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        /* Copy source region */
+        jcopy_block_row(src_buffer[offset_y],
+                        dst_buffer[offset_y] + x_crop_blocks, comp_width);
+        if (x_crop_blocks > 0) {
+          /* Reflect to left */
+          dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks;
+          for (dst_blk_x = x_crop_blocks; dst_blk_x > 0;) {
+            src_row_ptr = dst_row_ptr;      /* (re)set axis of reflection */
+            for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
+                 src_blk_x--, dst_blk_x--) {
+              dst_ptr = *(--dst_row_ptr);   /* destination goes left */
+              src_ptr = *src_row_ptr++;     /* source goes right */
+              /* This unrolled loop doesn't need to know which row it's on. */
+              for (k = 0; k < DCTSIZE2; k += 2) {
+                *dst_ptr++ = *src_ptr++;    /* copy even column */
+                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
+                                               change */
+              }
+            }
+          }
+        }
+        if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
+          /* Reflect to right */
+          dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks + comp_width;
+          for (dst_blk_x = compptr->width_in_blocks - x_crop_blocks - comp_width;
+               dst_blk_x > 0;) {
+            src_row_ptr = dst_row_ptr;      /* (re)set axis of reflection */
+            for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
+                 src_blk_x--, dst_blk_x--) {
+              dst_ptr = *dst_row_ptr++;     /* destination goes right */
+              src_ptr = *(--src_row_ptr);   /* source goes left */
+              /* This unrolled loop doesn't need to know which row it's on. */
+              for (k = 0; k < DCTSIZE2; k += 2) {
+                *dst_ptr++ = *src_ptr++;    /* copy even column */
+                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
+                                               change */
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_wipe(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+        JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+        jvirt_barray_ptr *src_coef_arrays,
+        JDIMENSION drop_width, JDIMENSION drop_height)
+/* Wipe - discard image contents of specified region and fill with zero
+ * (neutral gray)
+ */
+{
+  JDIMENSION x_wipe_blocks, wipe_width;
+  JDIMENSION y_wipe_blocks, wipe_bottom;
+  int ci, offset_y;
+  JBLOCKARRAY buffer;
+  jpeg_component_info *compptr;
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
+    wipe_width = drop_width * compptr->h_samp_factor;
+    y_wipe_blocks = y_crop_offset * compptr->v_samp_factor;
+    wipe_bottom = drop_height * compptr->v_samp_factor + y_wipe_blocks;
+    for (; y_wipe_blocks < wipe_bottom;
+         y_wipe_blocks += compptr->v_samp_factor) {
+      buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        MEMZERO(buffer[offset_y] + x_wipe_blocks, wipe_width * sizeof(JBLOCK));
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_flatten(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+           JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
+           jvirt_barray_ptr *src_coef_arrays,
+           JDIMENSION drop_width, JDIMENSION drop_height)
+/* Flatten - discard image contents of specified region, similarly to wipe,
+ * but fill with the average of adjacent blocks instead of zero.
+ */
+{
+  JDIMENSION x_wipe_blocks, wipe_width, wipe_right;
+  JDIMENSION y_wipe_blocks, wipe_bottom, blk_x;
+  int ci, offset_y, dc_left_value, dc_right_value, average;
+  JBLOCKARRAY buffer;
+  jpeg_component_info *compptr;
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
+    wipe_width = drop_width * compptr->h_samp_factor;
+    wipe_right = wipe_width + x_wipe_blocks;
+    y_wipe_blocks = y_crop_offset * compptr->v_samp_factor;
+    wipe_bottom = drop_height * compptr->v_samp_factor + y_wipe_blocks;
+    for (; y_wipe_blocks < wipe_bottom;
+         y_wipe_blocks += compptr->v_samp_factor) {
+      buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        MEMZERO(buffer[offset_y] + x_wipe_blocks, wipe_width * sizeof(JBLOCK));
+        if (x_wipe_blocks > 0) {
+          dc_left_value = buffer[offset_y][x_wipe_blocks - 1][0];
+          if (wipe_right < compptr->width_in_blocks) {
+            dc_right_value = buffer[offset_y][wipe_right][0];
+            average = (dc_left_value + dc_right_value) >> 1;
+          } else {
+            average = dc_left_value;
+          }
+        } else if (wipe_right < compptr->width_in_blocks) {
+          average = buffer[offset_y][wipe_right][0];
+        } else continue;
+        for (blk_x = x_wipe_blocks; blk_x < wipe_right; blk_x++) {
+          buffer[offset_y][blk_x][0] = (JCOEF)average;
+        }
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_reflect(j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+           JDIMENSION x_crop_offset, jvirt_barray_ptr *src_coef_arrays,
+           JDIMENSION drop_width, JDIMENSION drop_height)
+/* Reflect - discard image contents of specified region, similarly to wipe,
+ * but fill with repeated reflections of the outside region instead of zero.
+ * NB: y_crop_offset is assumed to be zero.
+ */
+{
+  JDIMENSION x_wipe_blocks, wipe_width;
+  JDIMENSION y_wipe_blocks, wipe_bottom;
+  JDIMENSION src_blk_x, dst_blk_x;
+  int ci, k, offset_y;
+  JBLOCKARRAY buffer;
+  JBLOCKROW src_row_ptr, dst_row_ptr;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
+    wipe_width = drop_width * compptr->h_samp_factor;
+    wipe_bottom = drop_height * compptr->v_samp_factor;
+    for (y_wipe_blocks = 0; y_wipe_blocks < wipe_bottom;
+         y_wipe_blocks += compptr->v_samp_factor) {
+      buffer = (*srcinfo->mem->access_virt_barray)
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], y_wipe_blocks,
+         (JDIMENSION)compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+        if (x_wipe_blocks > 0) {
+          /* Reflect from left */
+          dst_row_ptr = buffer[offset_y] + x_wipe_blocks;
+          for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
+            src_row_ptr = dst_row_ptr;     /* (re)set axis of reflection */
+            for (src_blk_x = x_wipe_blocks;
+                 src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
+              dst_ptr = *dst_row_ptr++;    /* destination goes right */
+              src_ptr = *(--src_row_ptr);  /* source goes left */
+              /* this unrolled loop doesn't need to know which row it's on... */
+              for (k = 0; k < DCTSIZE2; k += 2) {
+                *dst_ptr++ = *src_ptr++;   /* copy even column */
+                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign change */
+              }
+            }
+          }
+        } else if (compptr->width_in_blocks > x_wipe_blocks + wipe_width) {
+          /* Reflect from right */
+          dst_row_ptr = buffer[offset_y] + x_wipe_blocks + wipe_width;
+          for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
+            src_row_ptr = dst_row_ptr;     /* (re)set axis of reflection */
+            src_blk_x = compptr->width_in_blocks - x_wipe_blocks - wipe_width;
+            for (; src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
+              dst_ptr = *(--dst_row_ptr);  /* destination goes left */
+              src_ptr = *src_row_ptr++;    /* source goes right */
+              /* this unrolled loop doesn't need to know which row it's on... */
+              for (k = 0; k < DCTSIZE2; k += 2) {
+                *dst_ptr++ = *src_ptr++;   /* copy even column */
+                *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign change */
+              }
+            }
+          }
+        } else {
+          MEMZERO(buffer[offset_y] + x_wipe_blocks,
+                  wipe_width * sizeof(JBLOCK));
+        }
       }
     }
   }
@@ -224,8 +816,7 @@
         ((j_common_ptr)srcinfo, dst_coef_arrays[ci], dst_blk_y,
          (JDIMENSION)compptr->v_samp_factor, TRUE);
       src_buffer = (*srcinfo->mem->access_virt_barray)
-        ((j_common_ptr)srcinfo, src_coef_arrays[ci],
-         dst_blk_y + y_crop_blocks,
+        ((j_common_ptr)srcinfo, src_coef_arrays[ci], dst_blk_y + y_crop_blocks,
          (JDIMENSION)compptr->v_samp_factor, FALSE);
       for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
         dst_row_ptr = dst_buffer[offset_y];
@@ -238,8 +829,9 @@
             src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
             /* this unrolled loop doesn't need to know which row it's on... */
             for (k = 0; k < DCTSIZE2; k += 2) {
-              *dst_ptr++ = *src_ptr++;   /* copy even column */
-              *dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
+              *dst_ptr++ = *src_ptr++;    /* copy even column */
+              *dst_ptr++ = -(*src_ptr++); /* copy odd column with sign
+                                             change */
             }
           } else {
             /* Copy last partial block(s) verbatim */
@@ -318,14 +910,13 @@
                 *dst_ptr++ = *src_ptr++;
               /* copy odd row with sign change */
               for (j = 0; j < DCTSIZE; j++)
-                *dst_ptr++ = - *src_ptr++;
+                *dst_ptr++ = -(*src_ptr++);
             }
           }
         } else {
           /* Just copy row verbatim. */
           jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
-                          dst_buffer[offset_y],
-                          compptr->width_in_blocks);
+                          dst_buffer[offset_y], compptr->width_in_blocks);
         }
       }
     }
@@ -599,11 +1190,11 @@
                 /* For even row, negate every odd column. */
                 for (j = 0; j < DCTSIZE; j += 2) {
                   *dst_ptr++ = *src_ptr++;
-                  *dst_ptr++ = - *src_ptr++;
+                  *dst_ptr++ = -(*src_ptr++);
                 }
                 /* For odd row, negate every even column. */
                 for (j = 0; j < DCTSIZE; j += 2) {
-                  *dst_ptr++ = - *src_ptr++;
+                  *dst_ptr++ = -(*src_ptr++);
                   *dst_ptr++ = *src_ptr++;
                 }
               }
@@ -614,7 +1205,7 @@
                 for (j = 0; j < DCTSIZE; j++)
                   *dst_ptr++ = *src_ptr++;
                 for (j = 0; j < DCTSIZE; j++)
-                  *dst_ptr++ = - *src_ptr++;
+                  *dst_ptr++ = -(*src_ptr++);
               }
             }
           }
@@ -630,7 +1221,7 @@
                 src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
               for (i = 0; i < DCTSIZE2; i += 2) {
                 *dst_ptr++ = *src_ptr++;
-                *dst_ptr++ = - *src_ptr++;
+                *dst_ptr++ = -(*src_ptr++);
               }
             } else {
               /* Any remaining right-edge blocks are only copied. */
@@ -786,7 +1377,7 @@
  * The routine returns TRUE if the spec string is valid, FALSE if not.
  *
  * The crop spec string should have the format
- *      <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
+ *      <width>[{fr}]x<height>[{fr}]{+-}<xoffset>{+-}<yoffset>
  * where width, height, xoffset, and yoffset are unsigned integers.
  * Each of the elements can be omitted to indicate a default value.
  * (A weakness of this style is that it is not possible to omit xoffset
@@ -811,6 +1402,9 @@
     if (*spec == 'f' || *spec == 'F') {
       spec++;
       info->crop_width_set = JCROP_FORCE;
+    } else if (*spec == 'r' || *spec == 'R') {
+      spec++;
+      info->crop_width_set = JCROP_REFLECT;
     } else
       info->crop_width_set = JCROP_POS;
   }
@@ -822,6 +1416,9 @@
     if (*spec == 'f' || *spec == 'F') {
       spec++;
       info->crop_height_set = JCROP_FORCE;
+    } else if (*spec == 'r' || *spec == 'R') {
+      spec++;
+      info->crop_height_set = JCROP_REFLECT;
     } else
       info->crop_height_set = JCROP_POS;
   }
@@ -896,10 +1493,10 @@
   jvirt_barray_ptr *coef_arrays;
   boolean need_workspace, transpose_it;
   jpeg_component_info *compptr;
-  JDIMENSION xoffset, yoffset;
+  JDIMENSION xoffset, yoffset, dtemp;
   JDIMENSION width_in_iMCUs, height_in_iMCUs;
   JDIMENSION width_in_blocks, height_in_blocks;
-  int ci, h_samp_factor, v_samp_factor;
+  int itemp, ci, h_samp_factor, v_samp_factor;
 
   /* Determine number of components in output image */
   if (info->force_grayscale &&
@@ -985,39 +1582,129 @@
       info->crop_xoffset = 0;   /* default to +0 */
     if (info->crop_yoffset_set == JCROP_UNSET)
       info->crop_yoffset = 0;   /* default to +0 */
-    if (info->crop_xoffset >= info->output_width ||
-        info->crop_yoffset >= info->output_height)
-      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
-    if (info->crop_width_set == JCROP_UNSET)
+    if (info->crop_width_set == JCROP_UNSET) {
+      if (info->crop_xoffset >= info->output_width)
+        ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
       info->crop_width = info->output_width - info->crop_xoffset;
-    if (info->crop_height_set == JCROP_UNSET)
+    } else {
+      /* Check for crop extension */
+      if (info->crop_width > info->output_width) {
+        /* Crop extension does not work when transforming! */
+        if (info->transform != JXFORM_NONE ||
+            info->crop_xoffset >= info->crop_width ||
+            info->crop_xoffset > info->crop_width - info->output_width)
+          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      } else {
+        if (info->crop_xoffset >= info->output_width ||
+            info->crop_width <= 0 ||
+            info->crop_xoffset > info->output_width - info->crop_width)
+          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      }
+    }
+    if (info->crop_height_set == JCROP_UNSET) {
+      if (info->crop_yoffset >= info->output_height)
+        ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
       info->crop_height = info->output_height - info->crop_yoffset;
-    /* Ensure parameters are valid */
-    if (info->crop_width <= 0 || info->crop_width > info->output_width ||
-        info->crop_height <= 0 || info->crop_height > info->output_height ||
-        info->crop_xoffset > info->output_width - info->crop_width ||
-        info->crop_yoffset > info->output_height - info->crop_height)
-      ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+    } else {
+      /* Check for crop extension */
+      if (info->crop_height > info->output_height) {
+        /* Crop extension does not work when transforming! */
+        if (info->transform != JXFORM_NONE ||
+            info->crop_yoffset >= info->crop_height ||
+            info->crop_yoffset > info->crop_height - info->output_height)
+          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      } else {
+        if (info->crop_yoffset >= info->output_height ||
+            info->crop_height <= 0 ||
+            info->crop_yoffset > info->output_height - info->crop_height)
+          ERREXIT(srcinfo, JERR_BAD_CROP_SPEC);
+      }
+    }
     /* Convert negative crop offsets into regular offsets */
-    if (info->crop_xoffset_set == JCROP_NEG)
-      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
-    else
+    if (info->crop_xoffset_set != JCROP_NEG)
       xoffset = info->crop_xoffset;
-    if (info->crop_yoffset_set == JCROP_NEG)
-      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
+    else if (info->crop_width > info->output_width) /* crop extension */
+      xoffset = info->crop_width - info->output_width - info->crop_xoffset;
     else
+      xoffset = info->output_width - info->crop_width - info->crop_xoffset;
+    if (info->crop_yoffset_set != JCROP_NEG)
       yoffset = info->crop_yoffset;
+    else if (info->crop_height > info->output_height) /* crop extension */
+      yoffset = info->crop_height - info->output_height - info->crop_yoffset;
+    else
+      yoffset = info->output_height - info->crop_height - info->crop_yoffset;
     /* Now adjust so that upper left corner falls at an iMCU boundary */
-    if (info->crop_width_set == JCROP_FORCE)
-      info->output_width = info->crop_width;
-    else
-      info->output_width =
-        info->crop_width + (xoffset % info->iMCU_sample_width);
-    if (info->crop_height_set == JCROP_FORCE)
-      info->output_height = info->crop_height;
-    else
-      info->output_height =
-        info->crop_height + (yoffset % info->iMCU_sample_height);
+    switch (info->transform) {
+    case JXFORM_DROP:
+      /* Ensure the effective drop region will not exceed the requested */
+      itemp = info->iMCU_sample_width;
+      dtemp = itemp - 1 - ((xoffset + itemp - 1) % itemp);
+      xoffset += dtemp;
+      if (info->crop_width <= dtemp)
+        info->drop_width = 0;
+      else if (xoffset + info->crop_width - dtemp == info->output_width)
+        /* Matching right edge: include partial iMCU */
+        info->drop_width = (info->crop_width - dtemp + itemp - 1) / itemp;
+      else
+        info->drop_width = (info->crop_width - dtemp) / itemp;
+      itemp = info->iMCU_sample_height;
+      dtemp = itemp - 1 - ((yoffset + itemp - 1) % itemp);
+      yoffset += dtemp;
+      if (info->crop_height <= dtemp)
+        info->drop_height = 0;
+      else if (yoffset + info->crop_height - dtemp == info->output_height)
+        /* Matching bottom edge: include partial iMCU */
+        info->drop_height = (info->crop_height - dtemp + itemp - 1) / itemp;
+      else
+        info->drop_height = (info->crop_height - dtemp) / itemp;
+      /* Check if sampling factors match for dropping */
+      if (info->drop_width != 0 && info->drop_height != 0)
+        for (ci = 0; ci < info->num_components &&
+                     ci < info->drop_ptr->num_components; ci++) {
+          if (info->drop_ptr->comp_info[ci].h_samp_factor *
+              srcinfo->max_h_samp_factor !=
+              srcinfo->comp_info[ci].h_samp_factor *
+              info->drop_ptr->max_h_samp_factor)
+            ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
+              info->drop_ptr->comp_info[ci].h_samp_factor,
+              info->drop_ptr->max_h_samp_factor,
+              srcinfo->comp_info[ci].h_samp_factor,
+              srcinfo->max_h_samp_factor, 'h');
+          if (info->drop_ptr->comp_info[ci].v_samp_factor *
+              srcinfo->max_v_samp_factor !=
+              srcinfo->comp_info[ci].v_samp_factor *
+              info->drop_ptr->max_v_samp_factor)
+            ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
+              info->drop_ptr->comp_info[ci].v_samp_factor,
+              info->drop_ptr->max_v_samp_factor,
+              srcinfo->comp_info[ci].v_samp_factor,
+              srcinfo->max_v_samp_factor, 'v');
+        }
+      break;
+    case JXFORM_WIPE:
+      /* Ensure the effective wipe region will cover the requested */
+      info->drop_width = (JDIMENSION)jdiv_round_up
+        ((long)(info->crop_width + (xoffset % info->iMCU_sample_width)),
+         (long)info->iMCU_sample_width);
+      info->drop_height = (JDIMENSION)jdiv_round_up
+        ((long)(info->crop_height + (yoffset % info->iMCU_sample_height)),
+         (long)info->iMCU_sample_height);
+      break;
+    default:
+      /* Ensure the effective crop region will cover the requested */
+      if (info->crop_width_set == JCROP_FORCE ||
+          info->crop_width > info->output_width)
+        info->output_width = info->crop_width;
+      else
+        info->output_width =
+          info->crop_width + (xoffset % info->iMCU_sample_width);
+      if (info->crop_height_set == JCROP_FORCE ||
+          info->crop_height > info->output_height)
+        info->output_height = info->crop_height;
+      else
+        info->output_height =
+          info->crop_height + (yoffset % info->iMCU_sample_height);
+    }
     /* Save x/y offsets measured in iMCUs */
     info->x_crop_offset = xoffset / info->iMCU_sample_width;
     info->y_crop_offset = yoffset / info->iMCU_sample_height;
@@ -1033,7 +1720,9 @@
   transpose_it = FALSE;
   switch (info->transform) {
   case JXFORM_NONE:
-    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
+    if (info->x_crop_offset != 0 || info->y_crop_offset != 0 ||
+        info->output_width > srcinfo->output_width ||
+        info->output_height > srcinfo->output_height)
       need_workspace = TRUE;
     /* No workspace needed if neither cropping nor transforming */
     break;
@@ -1087,6 +1776,10 @@
     need_workspace = TRUE;
     transpose_it = TRUE;
     break;
+  case JXFORM_WIPE:
+    break;
+  case JXFORM_DROP:
+    break;
   }
 
   /* Allocate workspace if needed.
@@ -1190,47 +1883,47 @@
   if (length < 12) return; /* Length of an IFD entry */
 
   /* Discover byte order */
-  if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49)
+  if (data[0] == 0x49 && data[1] == 0x49)
     is_motorola = FALSE;
-  else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D)
+  else if (data[0] == 0x4D && data[1] == 0x4D)
     is_motorola = TRUE;
   else
     return;
 
   /* Check Tag Mark */
   if (is_motorola) {
-    if (GETJOCTET(data[2]) != 0) return;
-    if (GETJOCTET(data[3]) != 0x2A) return;
+    if (data[2] != 0) return;
+    if (data[3] != 0x2A) return;
   } else {
-    if (GETJOCTET(data[3]) != 0) return;
-    if (GETJOCTET(data[2]) != 0x2A) return;
+    if (data[3] != 0) return;
+    if (data[2] != 0x2A) return;
   }
 
   /* Get first IFD offset (offset to IFD0) */
   if (is_motorola) {
-    if (GETJOCTET(data[4]) != 0) return;
-    if (GETJOCTET(data[5]) != 0) return;
-    firstoffset = GETJOCTET(data[6]);
+    if (data[4] != 0) return;
+    if (data[5] != 0) return;
+    firstoffset = data[6];
     firstoffset <<= 8;
-    firstoffset += GETJOCTET(data[7]);
+    firstoffset += data[7];
   } else {
-    if (GETJOCTET(data[7]) != 0) return;
-    if (GETJOCTET(data[6]) != 0) return;
-    firstoffset = GETJOCTET(data[5]);
+    if (data[7] != 0) return;
+    if (data[6] != 0) return;
+    firstoffset = data[5];
     firstoffset <<= 8;
-    firstoffset += GETJOCTET(data[4]);
+    firstoffset += data[4];
   }
   if (firstoffset > length - 2) return; /* check end of data segment */
 
   /* Get the number of directory entries contained in this IFD */
   if (is_motorola) {
-    number_of_tags = GETJOCTET(data[firstoffset]);
+    number_of_tags = data[firstoffset];
     number_of_tags <<= 8;
-    number_of_tags += GETJOCTET(data[firstoffset + 1]);
+    number_of_tags += data[firstoffset + 1];
   } else {
-    number_of_tags = GETJOCTET(data[firstoffset + 1]);
+    number_of_tags = data[firstoffset + 1];
     number_of_tags <<= 8;
-    number_of_tags += GETJOCTET(data[firstoffset]);
+    number_of_tags += data[firstoffset];
   }
   if (number_of_tags == 0) return;
   firstoffset += 2;
@@ -1240,13 +1933,13 @@
     if (firstoffset > length - 12) return; /* check end of data segment */
     /* Get Tag number */
     if (is_motorola) {
-      tagnum = GETJOCTET(data[firstoffset]);
+      tagnum = data[firstoffset];
       tagnum <<= 8;
-      tagnum += GETJOCTET(data[firstoffset + 1]);
+      tagnum += data[firstoffset + 1];
     } else {
-      tagnum = GETJOCTET(data[firstoffset + 1]);
+      tagnum = data[firstoffset + 1];
       tagnum <<= 8;
-      tagnum += GETJOCTET(data[firstoffset]);
+      tagnum += data[firstoffset];
     }
     if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */
     if (--number_of_tags == 0) return;
@@ -1255,29 +1948,29 @@
 
   /* Get the ExifSubIFD offset */
   if (is_motorola) {
-    if (GETJOCTET(data[firstoffset + 8]) != 0) return;
-    if (GETJOCTET(data[firstoffset + 9]) != 0) return;
-    offset = GETJOCTET(data[firstoffset + 10]);
+    if (data[firstoffset + 8] != 0) return;
+    if (data[firstoffset + 9] != 0) return;
+    offset = data[firstoffset + 10];
     offset <<= 8;
-    offset += GETJOCTET(data[firstoffset + 11]);
+    offset += data[firstoffset + 11];
   } else {
-    if (GETJOCTET(data[firstoffset + 11]) != 0) return;
-    if (GETJOCTET(data[firstoffset + 10]) != 0) return;
-    offset = GETJOCTET(data[firstoffset + 9]);
+    if (data[firstoffset + 11] != 0) return;
+    if (data[firstoffset + 10] != 0) return;
+    offset = data[firstoffset + 9];
     offset <<= 8;
-    offset += GETJOCTET(data[firstoffset + 8]);
+    offset += data[firstoffset + 8];
   }
   if (offset > length - 2) return; /* check end of data segment */
 
   /* Get the number of directory entries contained in this SubIFD */
   if (is_motorola) {
-    number_of_tags = GETJOCTET(data[offset]);
+    number_of_tags = data[offset];
     number_of_tags <<= 8;
-    number_of_tags += GETJOCTET(data[offset + 1]);
+    number_of_tags += data[offset + 1];
   } else {
-    number_of_tags = GETJOCTET(data[offset + 1]);
+    number_of_tags = data[offset + 1];
     number_of_tags <<= 8;
-    number_of_tags += GETJOCTET(data[offset]);
+    number_of_tags += data[offset];
   }
   if (number_of_tags < 2) return;
   offset += 2;
@@ -1287,13 +1980,13 @@
     if (offset > length - 12) return; /* check end of data segment */
     /* Get Tag number */
     if (is_motorola) {
-      tagnum = GETJOCTET(data[offset]);
+      tagnum = data[offset];
       tagnum <<= 8;
-      tagnum += GETJOCTET(data[offset + 1]);
+      tagnum += data[offset + 1];
     } else {
-      tagnum = GETJOCTET(data[offset + 1]);
+      tagnum = data[offset + 1];
       tagnum <<= 8;
-      tagnum += GETJOCTET(data[offset]);
+      tagnum += data[offset];
     }
     if (tagnum == 0xA002 || tagnum == 0xA003) {
       if (tagnum == 0xA002)
@@ -1387,7 +2080,7 @@
   dstinfo->jpeg_height = info->output_height;
 #endif
 
-  /* Transpose destination image parameters */
+  /* Transpose destination image parameters, adjust quantization */
   switch (info->transform) {
   case JXFORM_TRANSPOSE:
   case JXFORM_TRANSVERSE:
@@ -1399,6 +2092,12 @@
 #endif
     transpose_critical_parameters(dstinfo);
     break;
+  case JXFORM_DROP:
+    if (info->drop_width != 0 && info->drop_height != 0)
+      adjust_quant(srcinfo, src_coef_arrays,
+                   info->drop_ptr, info->drop_coef_arrays,
+                   info->trim, dstinfo);
+    break;
   default:
 #if JPEG_LIB_VERSION < 80
     dstinfo->image_width = info->output_width;
@@ -1411,12 +2110,12 @@
   if (srcinfo->marker_list != NULL &&
       srcinfo->marker_list->marker == JPEG_APP0 + 1 &&
       srcinfo->marker_list->data_length >= 6 &&
-      GETJOCTET(srcinfo->marker_list->data[0]) == 0x45 &&
-      GETJOCTET(srcinfo->marker_list->data[1]) == 0x78 &&
-      GETJOCTET(srcinfo->marker_list->data[2]) == 0x69 &&
-      GETJOCTET(srcinfo->marker_list->data[3]) == 0x66 &&
-      GETJOCTET(srcinfo->marker_list->data[4]) == 0 &&
-      GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
+      srcinfo->marker_list->data[0] == 0x45 &&
+      srcinfo->marker_list->data[1] == 0x78 &&
+      srcinfo->marker_list->data[2] == 0x69 &&
+      srcinfo->marker_list->data[3] == 0x66 &&
+      srcinfo->marker_list->data[4] == 0 &&
+      srcinfo->marker_list->data[5] == 0) {
     /* Suppress output of JFIF marker */
     dstinfo->write_JFIF_header = FALSE;
     /* Adjust Exif image parameters */
@@ -1465,7 +2164,23 @@
    */
   switch (info->transform) {
   case JXFORM_NONE:
-    if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
+    if (info->output_width > srcinfo->output_width ||
+        info->output_height > srcinfo->output_height) {
+      if (info->output_width > srcinfo->output_width &&
+          info->crop_width_set == JCROP_REFLECT)
+        do_crop_ext_reflect(srcinfo, dstinfo,
+                            info->x_crop_offset, info->y_crop_offset,
+                            src_coef_arrays, dst_coef_arrays);
+      else if (info->output_width > srcinfo->output_width &&
+               info->crop_width_set == JCROP_FORCE)
+        do_crop_ext_flat(srcinfo, dstinfo,
+                         info->x_crop_offset, info->y_crop_offset,
+                         src_coef_arrays, dst_coef_arrays);
+      else
+        do_crop_ext_zero(srcinfo, dstinfo,
+                         info->x_crop_offset, info->y_crop_offset,
+                         src_coef_arrays, dst_coef_arrays);
+    } else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
       do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
               src_coef_arrays, dst_coef_arrays);
     break;
@@ -1501,6 +2216,30 @@
     do_rot_270(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
                src_coef_arrays, dst_coef_arrays);
     break;
+  case JXFORM_WIPE:
+    if (info->crop_width_set == JCROP_REFLECT &&
+        info->y_crop_offset == 0 && info->drop_height ==
+        (JDIMENSION)jdiv_round_up
+          ((long)info->output_height, (long)info->iMCU_sample_height) &&
+        (info->x_crop_offset == 0 ||
+         info->x_crop_offset + info->drop_width ==
+         (JDIMENSION)jdiv_round_up
+           ((long)info->output_width, (long)info->iMCU_sample_width)))
+      do_reflect(srcinfo, dstinfo, info->x_crop_offset,
+                 src_coef_arrays, info->drop_width, info->drop_height);
+    else if (info->crop_width_set == JCROP_FORCE)
+      do_flatten(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
+                 src_coef_arrays, info->drop_width, info->drop_height);
+    else
+      do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
+              src_coef_arrays, info->drop_width, info->drop_height);
+    break;
+  case JXFORM_DROP:
+    if (info->drop_width != 0 && info->drop_height != 0)
+      do_drop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
+              src_coef_arrays, info->drop_ptr, info->drop_coef_arrays,
+              info->drop_width, info->drop_height);
+    break;
   }
 }
 
@@ -1607,20 +2346,20 @@
     if (dstinfo->write_JFIF_header &&
         marker->marker == JPEG_APP0 &&
         marker->data_length >= 5 &&
-        GETJOCTET(marker->data[0]) == 0x4A &&
-        GETJOCTET(marker->data[1]) == 0x46 &&
-        GETJOCTET(marker->data[2]) == 0x49 &&
-        GETJOCTET(marker->data[3]) == 0x46 &&
-        GETJOCTET(marker->data[4]) == 0)
+        marker->data[0] == 0x4A &&
+        marker->data[1] == 0x46 &&
+        marker->data[2] == 0x49 &&
+        marker->data[3] == 0x46 &&
+        marker->data[4] == 0)
       continue;                 /* reject duplicate JFIF */
     if (dstinfo->write_Adobe_marker &&
         marker->marker == JPEG_APP0 + 14 &&
         marker->data_length >= 5 &&
-        GETJOCTET(marker->data[0]) == 0x41 &&
-        GETJOCTET(marker->data[1]) == 0x64 &&
-        GETJOCTET(marker->data[2]) == 0x6F &&
-        GETJOCTET(marker->data[3]) == 0x62 &&
-        GETJOCTET(marker->data[4]) == 0x65)
+        marker->data[0] == 0x41 &&
+        marker->data[1] == 0x64 &&
+        marker->data[2] == 0x6F &&
+        marker->data[3] == 0x62 &&
+        marker->data[4] == 0x65)
       continue;                 /* reject duplicate Adobe */
     jpeg_write_marker(dstinfo, marker->marker,
                       marker->data, marker->data_length);
diff --git a/src/third_party/libjpeg-turbo/transupp.h b/src/third_party/libjpeg-turbo/transupp.h
index 80264cc..ea6be1f 100644
--- a/src/third_party/libjpeg-turbo/transupp.h
+++ b/src/third_party/libjpeg-turbo/transupp.h
@@ -2,7 +2,7 @@
  * transupp.h
  *
  * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
+ * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2017, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
@@ -62,6 +62,17 @@
  * output image covers at least the requested region, but may cover more.)
  * The adjustment of the region dimensions may be optionally disabled.
  *
+ * A complementary lossless wipe option is provided to discard (gray out) data
+ * inside a given image region while losslessly preserving what is outside.
+ * A lossless drop option is also provided, which allows another JPEG image to
+ * be inserted ("dropped") into the source image data at a given position,
+ * replacing the existing image data at that position.  Both the source image
+ * and the drop image must have the same subsampling level.  It is best if they
+ * also have the same quantization (quality.)  Otherwise, the quantization of
+ * the output image will be adapted to accommodate the higher of the source
+ * image quality and the drop image quality.  The trim option can be used with
+ * the drop option to requantize the drop image to match the source image.
+ *
  * We also provide a lossless-resize option, which is kind of a lossless-crop
  * operation in the DCT coefficient block domain - it discards higher-order
  * coefficients and losslessly preserves lower-order coefficients of a
@@ -92,20 +103,23 @@
   JXFORM_TRANSVERSE,      /* transpose across UR-to-LL axis */
   JXFORM_ROT_90,          /* 90-degree clockwise rotation */
   JXFORM_ROT_180,         /* 180-degree rotation */
-  JXFORM_ROT_270          /* 270-degree clockwise (or 90 ccw) */
+  JXFORM_ROT_270,         /* 270-degree clockwise (or 90 ccw) */
+  JXFORM_WIPE,            /* wipe */
+  JXFORM_DROP             /* drop */
 } JXFORM_CODE;
 
 /*
  * Codes for crop parameters, which can individually be unspecified,
  * positive or negative for xoffset or yoffset,
- * positive or forced for width or height.
+ * positive or force or reflect for width or height.
  */
 
 typedef enum {
   JCROP_UNSET,
   JCROP_POS,
   JCROP_NEG,
-  JCROP_FORCE
+  JCROP_FORCE,
+  JCROP_REFLECT
 } JCROP_CODE;
 
 /*
@@ -120,7 +134,7 @@
   boolean perfect;              /* if TRUE, fail if partial MCUs are requested */
   boolean trim;                 /* if TRUE, trim partial MCUs as needed */
   boolean force_grayscale;      /* if TRUE, convert color image to grayscale */
-  boolean crop;                 /* if TRUE, crop source image */
+  boolean crop;                 /* if TRUE, crop or wipe source image, or drop */
   boolean slow_hflip;  /* For best performance, the JXFORM_FLIP_H transform
                           normally modifies the source coefficients in place.
                           Setting this to TRUE will instead use a slower,
@@ -133,14 +147,18 @@
    * These can be filled in by jtransform_parse_crop_spec().
    */
   JDIMENSION crop_width;        /* Width of selected region */
-  JCROP_CODE crop_width_set;    /* (forced disables adjustment) */
+  JCROP_CODE crop_width_set;    /* (force-disables adjustment) */
   JDIMENSION crop_height;       /* Height of selected region */
-  JCROP_CODE crop_height_set;   /* (forced disables adjustment) */
+  JCROP_CODE crop_height_set;   /* (force-disables adjustment) */
   JDIMENSION crop_xoffset;      /* X offset of selected region */
   JCROP_CODE crop_xoffset_set;  /* (negative measures from right edge) */
   JDIMENSION crop_yoffset;      /* Y offset of selected region */
   JCROP_CODE crop_yoffset_set;  /* (negative measures from bottom edge) */
 
+  /* Drop parameters: set by caller for drop request */
+  j_decompress_ptr drop_ptr;
+  jvirt_barray_ptr *drop_coef_arrays;
+
   /* Internal workspace: caller should not touch these */
   int num_components;           /* # of components in workspace */
   jvirt_barray_ptr *workspace_coef_arrays; /* workspace for transformations */
@@ -148,6 +166,8 @@
   JDIMENSION output_height;
   JDIMENSION x_crop_offset;     /* destination crop offsets measured in iMCUs */
   JDIMENSION y_crop_offset;
+  JDIMENSION drop_width;        /* drop/wipe dimensions measured in iMCUs */
+  JDIMENSION drop_height;
   int iMCU_sample_width;        /* destination iMCU size */
   int iMCU_sample_height;
 } jpeg_transform_info;
diff --git a/src/third_party/libjpeg-turbo/turbojpeg-jni.c b/src/third_party/libjpeg-turbo/turbojpeg-jni.c
index d0ca37d..1b728e3 100644
--- a/src/third_party/libjpeg-turbo/turbojpeg-jni.c
+++ b/src/third_party/libjpeg-turbo/turbojpeg-jni.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C)2011-2017 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2011-2020 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -35,59 +35,58 @@
 #include <jni.h>
 #include "java/org_libjpegturbo_turbojpeg_TJCompressor.h"
 #include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
+#include "java/org_libjpegturbo_turbojpeg_TJTransformer.h"
 #include "java/org_libjpegturbo_turbojpeg_TJ.h"
 
-#define PAD(v, p)  ((v + (p) - 1) & (~((p) - 1)))
-
-#define bailif0(f) { \
+#define BAILIF0(f) { \
   if (!(f) || (*env)->ExceptionCheck(env)) { \
     goto bailout; \
   } \
 }
 
-#define _throw(msg, exceptionClass) { \
+#define THROW(msg, exceptionClass) { \
   jclass _exccls = (*env)->FindClass(env, exceptionClass); \
   \
-  bailif0(_exccls); \
+  BAILIF0(_exccls); \
   (*env)->ThrowNew(env, _exccls, msg); \
   goto bailout; \
 }
 
-#define _throwtj() { \
+#define THROW_TJ() { \
   jclass _exccls; \
   jmethodID _excid; \
   jobject _excobj; \
   jstring _errstr; \
   \
-  bailif0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \
-  bailif0(_exccls = (*env)->FindClass(env, \
+  BAILIF0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \
+  BAILIF0(_exccls = (*env)->FindClass(env, \
     "org/libjpegturbo/turbojpeg/TJException")); \
-  bailif0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \
+  BAILIF0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \
                                        "(Ljava/lang/String;I)V")); \
-  bailif0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \
+  BAILIF0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \
                                       tjGetErrorCode(handle))); \
   (*env)->Throw(env, _excobj); \
   goto bailout; \
 }
 
-#define _throwarg(msg)  _throw(msg, "java/lang/IllegalArgumentException")
+#define THROW_ARG(msg)  THROW(msg, "java/lang/IllegalArgumentException")
 
-#define _throwmem() \
-  _throw("Memory allocation failure", "java/lang/OutOfMemoryError");
+#define THROW_MEM() \
+  THROW("Memory allocation failure", "java/lang/OutOfMemoryError");
 
-#define gethandle() \
+#define GET_HANDLE() \
   jclass _cls = (*env)->GetObjectClass(env, obj); \
   jfieldID _fid; \
   \
-  bailif0(_cls); \
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \
+  BAILIF0(_cls); \
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \
   handle = (tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid);
 
 #ifdef _WIN32
 #define setenv(envvar, value, dummy)  _putenv_s(envvar, value)
 #endif
 
-#define prop2env(property, envvar) { \
+#define PROP2ENV(property, envvar) { \
   if ((jName = (*env)->NewStringUTF(env, property)) != NULL && \
       (jValue = (*env)->CallStaticObjectMethod(env, cls, mid, \
                                                jName)) != NULL) { \
@@ -98,21 +97,27 @@
   } \
 }
 
-int ProcessSystemProperties(JNIEnv *env)
+#define SAFE_RELEASE(javaArray, cArray) { \
+  if (javaArray && cArray) \
+    (*env)->ReleasePrimitiveArrayCritical(env, javaArray, (void *)cArray, 0); \
+  cArray = NULL; \
+}
+
+static int ProcessSystemProperties(JNIEnv *env)
 {
   jclass cls;
   jmethodID mid;
   jstring jName, jValue;
   const char *value;
 
-  bailif0(cls = (*env)->FindClass(env, "java/lang/System"));
-  bailif0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty",
+  BAILIF0(cls = (*env)->FindClass(env, "java/lang/System"));
+  BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty",
     "(Ljava/lang/String;)Ljava/lang/String;"));
 
-  prop2env("turbojpeg.optimize", "TJ_OPTIMIZE");
-  prop2env("turbojpeg.arithmetic", "TJ_ARITHMETIC");
-  prop2env("turbojpeg.restart", "TJ_RESTART");
-  prop2env("turbojpeg.progressive", "TJ_PROGRESSIVE");
+  PROP2ENV("turbojpeg.optimize", "TJ_OPTIMIZE");
+  PROP2ENV("turbojpeg.arithmetic", "TJ_ARITHMETIC");
+  PROP2ENV("turbojpeg.restart", "TJ_RESTART");
+  PROP2ENV("turbojpeg.progressive", "TJ_PROGRESSIVE");
   return 0;
 
 bailout:
@@ -125,7 +130,7 @@
 {
   jint retval = (jint)tjBufSize(width, height, jpegSubsamp);
 
-  if (retval == -1) _throwarg(tjGetErrorStr());
+  if (retval == -1) THROW_ARG(tjGetErrorStr());
 
 bailout:
   return retval;
@@ -137,7 +142,7 @@
 {
   jint retval = (jint)tjBufSizeYUV2(width, pad, height, subsamp);
 
-  if (retval == -1) _throwarg(tjGetErrorStr());
+  if (retval == -1) THROW_ARG(tjGetErrorStr());
 
 bailout:
   return retval;
@@ -160,7 +165,7 @@
   jint retval = (jint)tjPlaneSizeYUV(componentID, width, stride, height,
                                      subsamp);
 
-  if (retval == -1) _throwarg(tjGetErrorStr());
+  if (retval == -1) THROW_ARG(tjGetErrorStr());
 
 bailout:
   return retval;
@@ -172,7 +177,7 @@
 {
   jint retval = (jint)tjPlaneWidth(componentID, width, subsamp);
 
-  if (retval == -1) _throwarg(tjGetErrorStr());
+  if (retval == -1) THROW_ARG(tjGetErrorStr());
 
 bailout:
   return retval;
@@ -184,7 +189,7 @@
 {
   jint retval = (jint)tjPlaneHeight(componentID, height, subsamp);
 
-  if (retval == -1) _throwarg(tjGetErrorStr());
+  if (retval == -1) THROW_ARG(tjGetErrorStr());
 
 bailout:
   return retval;
@@ -199,10 +204,10 @@
   tjhandle handle;
 
   if ((handle = tjInitCompress()) == NULL)
-    _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
+    THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
 
-  bailif0(cls = (*env)->GetObjectClass(env, obj));
-  bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+  BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
   (*env)->SetLongField(env, obj, fid, (size_t)handle);
 
 bailout:
@@ -219,35 +224,38 @@
   jsize arraySize = 0, actualPitch;
   unsigned char *srcBuf = NULL, *jpegBuf = NULL;
 
-  gethandle();
+  GET_HANDLE();
 
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
       height < 1 || pitch < 0)
-    _throwarg("Invalid argument in compress()");
+    THROW_ARG("Invalid argument in compress()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch;
   arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf];
   if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize)
-    _throwarg("Source buffer is not large enough");
+    THROW_ARG("Source buffer is not large enough");
   jpegSize = tjBufSize(width, height, jpegSubsamp);
   if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize)
-    _throwarg("Destination buffer is not large enough");
-
-  bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+    THROW_ARG("Destination buffer is not large enough");
 
   if (ProcessSystemProperties(env) < 0) goto bailout;
 
+  BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+
   if (tjCompress2(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]],
                   width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp,
-                  jpegQual, flags | TJFLAG_NOREALLOC) == -1)
-    _throwtj();
+                  jpegQual, flags | TJFLAG_NOREALLOC) == -1) {
+    SAFE_RELEASE(dst, jpegBuf);
+    SAFE_RELEASE(src, srcBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
-  if (srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
+  SAFE_RELEASE(dst, jpegBuf);
+  SAFE_RELEASE(src, srcBuf);
   return (jint)jpegSize;
 }
 
@@ -278,9 +286,9 @@
    jint jpegQual, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in compress()");
+    THROW_ARG("Invalid argument in compress()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when compressing from an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer.");
 
   return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width,
                                stride * sizeof(jint), height, pf, dst,
@@ -297,9 +305,9 @@
    jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in compress()");
+    THROW_ARG("Invalid argument in compress()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when compressing from an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer.");
 
   return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width,
                                stride * sizeof(jint), height, pf, dst,
@@ -318,71 +326,76 @@
   tjhandle handle = 0;
   unsigned long jpegSize = 0;
   jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL };
-  const unsigned char *srcPlanes[3];
+  const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL };
+  const unsigned char *srcPlanes[3] = { NULL, NULL, NULL };
+  int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 };
+  int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 };
   unsigned char *jpegBuf = NULL;
-  int *srcOffsets = NULL, *srcStrides = NULL;
   int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i;
 
-  gethandle();
+  GET_HANDLE();
 
   if (subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
-    _throwarg("Invalid argument in compressFromYUV()");
+    THROW_ARG("Invalid argument in compressFromYUV()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   if ((*env)->GetArrayLength(env, srcobjs) < nc)
-    _throwarg("Planes array is too small for the subsampling type");
+    THROW_ARG("Planes array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jSrcOffsets) < nc)
-    _throwarg("Offsets array is too small for the subsampling type");
+    THROW_ARG("Offsets array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jSrcStrides) < nc)
-    _throwarg("Strides array is too small for the subsampling type");
+    THROW_ARG("Strides array is too small for the subsampling type");
 
   jpegSize = tjBufSize(width, height, subsamp);
   if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize)
-    _throwarg("Destination buffer is not large enough");
+    THROW_ARG("Destination buffer is not large enough");
 
-  bailif0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
-  bailif0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
+  if (ProcessSystemProperties(env) < 0) goto bailout;
+
+  BAILIF0(srcOffsetsTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
+  for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i];
+  SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp);
+
+  BAILIF0(srcStridesTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
+  for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i];
+  SAFE_RELEASE(jSrcStrides, srcStridesTmp);
+
   for (i = 0; i < nc; i++) {
     int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp);
     int pw = tjPlaneWidth(i, width, subsamp);
 
     if (planeSize < 0 || pw < 0)
-      _throwarg(tjGetErrorStr());
+      THROW_ARG(tjGetErrorStr());
 
     if (srcOffsets[i] < 0)
-      _throwarg("Invalid argument in compressFromYUV()");
+      THROW_ARG("Invalid argument in compressFromYUV()");
     if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0)
-      _throwarg("Negative plane stride would cause memory to be accessed below plane boundary");
+      THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary");
 
-    bailif0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i));
-    if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < srcOffsets[i] + planeSize)
-      _throwarg("Source plane is not large enough");
+    BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i));
+    if ((*env)->GetArrayLength(env, jSrcPlanes[i]) <
+        srcOffsets[i] + planeSize)
+      THROW_ARG("Source plane is not large enough");
 
-    bailif0(srcPlanes[i] =
+    BAILIF0(srcPlanesTmp[i] =
             (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0));
-    srcPlanes[i] = &srcPlanes[i][srcOffsets[i]];
+    srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]];
+    SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]);
   }
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
-
-  if (ProcessSystemProperties(env) < 0) goto bailout;
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
   if (tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height,
                               subsamp, &jpegBuf, &jpegSize, jpegQual,
-                              flags | TJFLAG_NOREALLOC) == -1)
-    _throwtj();
+                              flags | TJFLAG_NOREALLOC) == -1) {
+    SAFE_RELEASE(dst, jpegBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
-  for (i = 0; i < nc; i++) {
-    if (srcPlanes[i] && jSrcPlanes[i])
-      (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i],
-                                            (unsigned char *)srcPlanes[i], 0);
-  }
-  if (srcStrides)
-    (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
-  if (srcOffsets)
-    (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
+  SAFE_RELEASE(dst, jpegBuf);
   return (jint)jpegSize;
 }
 
@@ -393,73 +406,79 @@
 {
   tjhandle handle = 0;
   jsize arraySize = 0, actualPitch;
+  unsigned char *srcBuf = NULL;
   jbyteArray jDstPlanes[3] = { NULL, NULL, NULL };
-  unsigned char *srcBuf = NULL, *dstPlanes[3];
-  int *dstOffsets = NULL, *dstStrides = NULL;
+  unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL };
+  unsigned char *dstPlanes[3] = { NULL, NULL, NULL };
+  int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 };
+  int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 };
   int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i;
 
-  gethandle();
+  GET_HANDLE();
 
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
       height < 1 || pitch < 0 || subsamp < 0 ||
       subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
-    _throwarg("Invalid argument in encodeYUV()");
+    THROW_ARG("Invalid argument in encodeYUV()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF ||
       org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   if ((*env)->GetArrayLength(env, dstobjs) < nc)
-    _throwarg("Planes array is too small for the subsampling type");
+    THROW_ARG("Planes array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jDstOffsets) < nc)
-    _throwarg("Offsets array is too small for the subsampling type");
+    THROW_ARG("Offsets array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jDstStrides) < nc)
-    _throwarg("Strides array is too small for the subsampling type");
+    THROW_ARG("Strides array is too small for the subsampling type");
 
   actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch;
   arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf];
   if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize)
-    _throwarg("Source buffer is not large enough");
+    THROW_ARG("Source buffer is not large enough");
 
-  bailif0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
-  bailif0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
+  BAILIF0(dstOffsetsTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
+  for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i];
+  SAFE_RELEASE(jDstOffsets, dstOffsetsTmp);
+
+  BAILIF0(dstStridesTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
+  for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i];
+  SAFE_RELEASE(jDstStrides, dstStridesTmp);
+
   for (i = 0; i < nc; i++) {
     int planeSize = tjPlaneSizeYUV(i, width, dstStrides[i], height, subsamp);
     int pw = tjPlaneWidth(i, width, subsamp);
 
     if (planeSize < 0 || pw < 0)
-      _throwarg(tjGetErrorStr());
+      THROW_ARG(tjGetErrorStr());
 
     if (dstOffsets[i] < 0)
-      _throwarg("Invalid argument in encodeYUV()");
+      THROW_ARG("Invalid argument in encodeYUV()");
     if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0)
-      _throwarg("Negative plane stride would cause memory to be accessed below plane boundary");
+      THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary");
 
-    bailif0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
-    if ((*env)->GetArrayLength(env, jDstPlanes[i]) < dstOffsets[i] + planeSize)
-      _throwarg("Destination plane is not large enough");
+    BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
+    if ((*env)->GetArrayLength(env, jDstPlanes[i]) <
+        dstOffsets[i] + planeSize)
+      THROW_ARG("Destination plane is not large enough");
 
-    bailif0(dstPlanes[i] =
+    BAILIF0(dstPlanesTmp[i] =
             (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0));
-    dstPlanes[i] = &dstPlanes[i][dstOffsets[i]];
+    dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]];
+    SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]);
   }
-  bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
 
   if (tjEncodeYUVPlanes(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]],
                         width, pitch, height, pf, dstPlanes, dstStrides,
-                        subsamp, flags) == -1)
-    _throwtj();
+                        subsamp, flags) == -1) {
+    SAFE_RELEASE(src, srcBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
-  for (i = 0; i < nc; i++) {
-    if (dstPlanes[i] && jDstPlanes[i])
-      (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
-                                            0);
-  }
-  if (dstStrides)
-    (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
-  if (dstOffsets)
-    (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
+  SAFE_RELEASE(src, srcBuf);
 }
 
 /* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */
@@ -479,9 +498,9 @@
    jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in encodeYUV()");
+    THROW_ARG("Invalid argument in encodeYUV()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when encoding from an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer.");
 
   TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width,
                          stride * sizeof(jint), height, pf, dstobjs,
@@ -491,7 +510,7 @@
   return;
 }
 
-JNIEXPORT void JNICALL TJCompressor_encodeYUV_12
+static void JNICALL TJCompressor_encodeYUV_12
   (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width,
    jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
 {
@@ -499,31 +518,34 @@
   jsize arraySize = 0;
   unsigned char *srcBuf = NULL, *dstBuf = NULL;
 
-  gethandle();
+  GET_HANDLE();
 
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
       height < 1 || pitch < 0)
-    _throwarg("Invalid argument in encodeYUV()");
+    THROW_ARG("Invalid argument in encodeYUV()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   arraySize = (pitch == 0) ? width * tjPixelSize[pf] * height : pitch * height;
   if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize)
-    _throwarg("Source buffer is not large enough");
+    THROW_ARG("Source buffer is not large enough");
   if ((*env)->GetArrayLength(env, dst) <
       (jsize)tjBufSizeYUV(width, height, subsamp))
-    _throwarg("Destination buffer is not large enough");
+    THROW_ARG("Destination buffer is not large enough");
 
-  bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
-  bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+  BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
   if (tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp,
-                   flags) == -1)
-    _throwtj();
+                   flags) == -1) {
+    SAFE_RELEASE(dst, dstBuf);
+    SAFE_RELEASE(src, srcBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
-  if (srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
+  SAFE_RELEASE(dst, dstBuf);
+  SAFE_RELEASE(src, srcBuf);
 }
 
 /* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */
@@ -541,9 +563,9 @@
    jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in encodeYUV()");
+    THROW_ARG("Invalid argument in encodeYUV()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when encoding from an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer.");
 
   TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width,
                             stride * sizeof(jint), height, pf, dst, subsamp,
@@ -559,9 +581,9 @@
 {
   tjhandle handle = 0;
 
-  gethandle();
+  GET_HANDLE();
 
-  if (tjDestroy(handle) == -1) _throwtj();
+  if (tjDestroy(handle) == -1) THROW_TJ();
   (*env)->SetLongField(env, obj, _fid, 0);
 
 bailout:
@@ -577,10 +599,10 @@
   tjhandle handle;
 
   if ((handle = tjInitDecompress()) == NULL)
-    _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
+    THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
 
-  bailif0(cls = (*env)->GetObjectClass(env, obj));
-  bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+  BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
   (*env)->SetLongField(env, obj, fid, (size_t)handle);
 
 bailout:
@@ -599,17 +621,17 @@
   jobjectArray sfjava = NULL;
 
   if ((sf = tjGetScalingFactors(&n)) == NULL || n == 0)
-    _throwarg(tjGetErrorStr());
+    THROW_ARG(tjGetErrorStr());
 
-  bailif0(sfcls = (*env)->FindClass(env,
+  BAILIF0(sfcls = (*env)->FindClass(env,
     "org/libjpegturbo/turbojpeg/TJScalingFactor"));
-  bailif0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
+  BAILIF0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
 
   for (i = 0; i < n; i++) {
-    bailif0(sfobj = (*env)->AllocObject(env, sfcls));
-    bailif0(fid = (*env)->GetFieldID(env, sfcls, "num", "I"));
+    BAILIF0(sfobj = (*env)->AllocObject(env, sfcls));
+    BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "num", "I"));
     (*env)->SetIntField(env, sfobj, fid, sf[i].num);
-    bailif0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I"));
+    BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I"));
     (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
     (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
   }
@@ -626,33 +648,34 @@
   unsigned char *jpegBuf = NULL;
   int width = 0, height = 0, jpegSubsamp = -1, jpegColorspace = -1;
 
-  gethandle();
+  GET_HANDLE();
 
   if ((*env)->GetArrayLength(env, src) < jpegSize)
-    _throwarg("Source buffer is not large enough");
+    THROW_ARG("Source buffer is not large enough");
 
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
 
   if (tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize, &width,
-                          &height, &jpegSubsamp, &jpegColorspace) == -1)
-    _throwtj();
+                          &height, &jpegSubsamp, &jpegColorspace) == -1) {
+    SAFE_RELEASE(src, jpegBuf);
+    THROW_TJ();
+  }
 
-  (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
-  jpegBuf = NULL;
+  SAFE_RELEASE(src, jpegBuf);
 
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
   (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
   if ((_fid = (*env)->GetFieldID(env, _cls, "jpegColorspace", "I")) == 0)
     (*env)->ExceptionClear(env);
   else
     (*env)->SetIntField(env, obj, _fid, jpegColorspace);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
   (*env)->SetIntField(env, obj, _fid, width);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
   (*env)->SetIntField(env, obj, _fid, height);
 
 bailout:
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
+  SAFE_RELEASE(src, jpegBuf);
 }
 
 static void TJDecompressor_decompress
@@ -664,31 +687,34 @@
   jsize arraySize = 0, actualPitch;
   unsigned char *jpegBuf = NULL, *dstBuf = NULL;
 
-  gethandle();
+  GET_HANDLE();
 
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in decompress()");
+    THROW_ARG("Invalid argument in decompress()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   if ((*env)->GetArrayLength(env, src) < jpegSize)
-    _throwarg("Source buffer is not large enough");
+    THROW_ARG("Source buffer is not large enough");
   actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch;
   arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf];
   if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize)
-    _throwarg("Destination buffer is not large enough");
+    THROW_ARG("Destination buffer is not large enough");
 
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
-  bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
   if (tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
                     &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width,
-                    pitch, height, pf, flags) == -1)
-    _throwtj();
+                    pitch, height, pf, flags) == -1) {
+    SAFE_RELEASE(dst, dstBuf);
+    SAFE_RELEASE(src, jpegBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
+  SAFE_RELEASE(dst, dstBuf);
+  SAFE_RELEASE(src, jpegBuf);
 }
 
 /* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */
@@ -715,9 +741,9 @@
    jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in decompress()");
+    THROW_ARG("Invalid argument in decompress()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when decompressing to an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer.");
 
   TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y,
                             width, stride * sizeof(jint), height, pf, flags);
@@ -732,9 +758,9 @@
    jint width, jint stride, jint height, jint pf, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in decompress()");
+    THROW_ARG("Invalid argument in decompress()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when decompressing to an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer.");
 
   TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0,
                             width, stride * sizeof(jint), height, pf, flags);
@@ -750,22 +776,25 @@
    jintArray jDstStrides, jint desiredHeight, jint flags)
 {
   tjhandle handle = 0;
+  unsigned char *jpegBuf = NULL;
   jbyteArray jDstPlanes[3] = { NULL, NULL, NULL };
-  unsigned char *jpegBuf = NULL, *dstPlanes[3];
-  int *dstOffsets = NULL, *dstStrides = NULL;
+  unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL };
+  unsigned char *dstPlanes[3] = { NULL, NULL, NULL };
+  int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 };
+  int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 };
   int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0;
   int nc = 0, i, width, height, scaledWidth, scaledHeight, nsf = 0;
   tjscalingfactor *sf;
 
-  gethandle();
+  GET_HANDLE();
 
   if ((*env)->GetArrayLength(env, src) < jpegSize)
-    _throwarg("Source buffer is not large enough");
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
+    THROW_ARG("Source buffer is not large enough");
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
   jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
   jpegWidth = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
   jpegHeight = (int)(*env)->GetIntField(env, obj, _fid);
 
   nc = (jpegSubsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3);
@@ -776,7 +805,7 @@
   if (height == 0) height = jpegHeight;
   sf = tjGetScalingFactors(&nsf);
   if (!sf || nsf < 1)
-    _throwarg(tjGetErrorStr());
+    THROW_ARG(tjGetErrorStr());
   for (i = 0; i < nsf; i++) {
     scaledWidth = TJSCALED(jpegWidth, sf[i]);
     scaledHeight = TJSCALED(jpegHeight, sf[i]);
@@ -784,49 +813,52 @@
       break;
   }
   if (i >= nsf)
-    _throwarg("Could not scale down to desired image dimensions");
+    THROW_ARG("Could not scale down to desired image dimensions");
 
-  bailif0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
-  bailif0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
+  BAILIF0(dstOffsetsTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0));
+  for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i];
+  SAFE_RELEASE(jDstOffsets, dstOffsetsTmp);
+
+  BAILIF0(dstStridesTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0));
+  for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i];
+  SAFE_RELEASE(jDstStrides, dstStridesTmp);
+
   for (i = 0; i < nc; i++) {
     int planeSize = tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight,
                                    jpegSubsamp);
     int pw = tjPlaneWidth(i, scaledWidth, jpegSubsamp);
 
     if (planeSize < 0 || pw < 0)
-      _throwarg(tjGetErrorStr());
+      THROW_ARG(tjGetErrorStr());
 
     if (dstOffsets[i] < 0)
-      _throwarg("Invalid argument in decompressToYUV()");
+      THROW_ARG("Invalid argument in decompressToYUV()");
     if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0)
-      _throwarg("Negative plane stride would cause memory to be accessed below plane boundary");
+      THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary");
 
-    bailif0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
-    if ((*env)->GetArrayLength(env, jDstPlanes[i]) < dstOffsets[i] + planeSize)
-      _throwarg("Destination plane is not large enough");
+    BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
+    if ((*env)->GetArrayLength(env, jDstPlanes[i]) <
+        dstOffsets[i] + planeSize)
+      THROW_ARG("Destination plane is not large enough");
 
-    bailif0(dstPlanes[i] =
+    BAILIF0(dstPlanesTmp[i] =
             (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0));
-    dstPlanes[i] = &dstPlanes[i][dstOffsets[i]];
+    dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]];
+    SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]);
   }
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
 
   if (tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize,
                               dstPlanes, desiredWidth, dstStrides,
-                              desiredHeight, flags) == -1)
-    _throwtj();
+                              desiredHeight, flags) == -1) {
+    SAFE_RELEASE(src, jpegBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
-  for (i = 0; i < nc; i++) {
-    if (dstPlanes[i] && jDstPlanes[i])
-      (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
-                                            0);
-  }
-  if (dstStrides)
-    (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
-  if (dstOffsets)
-    (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
+  SAFE_RELEASE(src, jpegBuf);
 }
 
 /* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */
@@ -838,30 +870,33 @@
   unsigned char *jpegBuf = NULL, *dstBuf = NULL;
   int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0;
 
-  gethandle();
+  GET_HANDLE();
 
   if ((*env)->GetArrayLength(env, src) < jpegSize)
-    _throwarg("Source buffer is not large enough");
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
+    THROW_ARG("Source buffer is not large enough");
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
   jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
   jpegWidth = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
   jpegHeight = (int)(*env)->GetIntField(env, obj, _fid);
   if ((*env)->GetArrayLength(env, dst) <
       (jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp))
-    _throwarg("Destination buffer is not large enough");
+    THROW_ARG("Destination buffer is not large enough");
 
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
-  bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+  BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
   if (tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
-                        flags) == -1)
-    _throwtj();
+                        flags) == -1) {
+    SAFE_RELEASE(dst, dstBuf);
+    SAFE_RELEASE(src, jpegBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
+  SAFE_RELEASE(dst, dstBuf);
+  SAFE_RELEASE(src, jpegBuf);
 }
 
 static void TJDecompressor_decodeYUV
@@ -872,72 +907,77 @@
   tjhandle handle = 0;
   jsize arraySize = 0, actualPitch;
   jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL };
-  const unsigned char *srcPlanes[3];
+  const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL };
+  const unsigned char *srcPlanes[3] = { NULL, NULL, NULL };
+  int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 };
+  int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 };
   unsigned char *dstBuf = NULL;
-  int *srcOffsets = NULL, *srcStrides = NULL;
   int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i;
 
-  gethandle();
+  GET_HANDLE();
 
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp < 0 ||
       subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
-    _throwarg("Invalid argument in decodeYUV()");
+    THROW_ARG("Invalid argument in decodeYUV()");
   if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF ||
       org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
-    _throwarg("Mismatch between Java and C API");
+    THROW_ARG("Mismatch between Java and C API");
 
   if ((*env)->GetArrayLength(env, srcobjs) < nc)
-    _throwarg("Planes array is too small for the subsampling type");
+    THROW_ARG("Planes array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jSrcOffsets) < nc)
-    _throwarg("Offsets array is too small for the subsampling type");
+    THROW_ARG("Offsets array is too small for the subsampling type");
   if ((*env)->GetArrayLength(env, jSrcStrides) < nc)
-    _throwarg("Strides array is too small for the subsampling type");
+    THROW_ARG("Strides array is too small for the subsampling type");
 
   actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch;
   arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf];
   if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize)
-    _throwarg("Destination buffer is not large enough");
+    THROW_ARG("Destination buffer is not large enough");
 
-  bailif0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
-  bailif0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
+  BAILIF0(srcOffsetsTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0));
+  for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i];
+  SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp);
+
+  BAILIF0(srcStridesTmp =
+          (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0));
+  for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i];
+  SAFE_RELEASE(jSrcStrides, srcStridesTmp);
+
   for (i = 0; i < nc; i++) {
     int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp);
     int pw = tjPlaneWidth(i, width, subsamp);
 
     if (planeSize < 0 || pw < 0)
-      _throwarg(tjGetErrorStr());
+      THROW_ARG(tjGetErrorStr());
 
     if (srcOffsets[i] < 0)
-      _throwarg("Invalid argument in decodeYUV()");
+      THROW_ARG("Invalid argument in decodeYUV()");
     if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0)
-      _throwarg("Negative plane stride would cause memory to be accessed below plane boundary");
+      THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary");
 
-    bailif0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i));
-    if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < srcOffsets[i] + planeSize)
-      _throwarg("Source plane is not large enough");
+    BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i));
+    if ((*env)->GetArrayLength(env, jSrcPlanes[i]) <
+        srcOffsets[i] + planeSize)
+      THROW_ARG("Source plane is not large enough");
 
-    bailif0(srcPlanes[i] =
+    BAILIF0(srcPlanesTmp[i] =
             (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0));
-    srcPlanes[i] = &srcPlanes[i][srcOffsets[i]];
+    srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]];
+    SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]);
   }
-  bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+  BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
   if (tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp,
                         &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width,
-                        pitch, height, pf, flags) == -1)
-    _throwtj();
+                        pitch, height, pf, flags) == -1) {
+    SAFE_RELEASE(dst, dstBuf);
+    THROW_TJ();
+  }
 
 bailout:
-  if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
-  for (i = 0; i < nc; i++) {
-    if (srcPlanes[i] && jSrcPlanes[i])
-      (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i],
-                                            (unsigned char *)srcPlanes[i], 0);
-  }
-  if (srcStrides)
-    (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
-  if (srcOffsets)
-    (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
+  SAFE_RELEASE(dst, dstBuf);
 }
 
 /* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */
@@ -958,9 +998,9 @@
    jint width, jint stride, jint height, jint pf, jint flags)
 {
   if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
-    _throwarg("Invalid argument in decodeYUV()");
+    THROW_ARG("Invalid argument in decodeYUV()");
   if (tjPixelSize[pf] != sizeof(jint))
-    _throwarg("Pixel format must be 32-bit when decoding to an integer buffer.");
+    THROW_ARG("Pixel format must be 32-bit when decoding to an integer buffer.");
 
   TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
                            subsamp, dst, sizeof(jint), x, y, width,
@@ -979,10 +1019,10 @@
   tjhandle handle;
 
   if ((handle = tjInitTransform()) == NULL)
-    _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
+    THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
 
-  bailif0(cls = (*env)->GetObjectClass(env, obj));
-  bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+  BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
   (*env)->SetLongField(env, obj, fid, (size_t)handle);
 
 bailout:
@@ -1007,43 +1047,43 @@
   jmethodID mid;
   jfieldID fid;
 
-  bailif0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs,
+  BAILIF0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs,
     sizeof(short) * arrayRegion.w * arrayRegion.h));
-  bailif0(cls = (*env)->FindClass(env, "java/nio/ByteOrder"));
-  bailif0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder",
+  BAILIF0(cls = (*env)->FindClass(env, "java/nio/ByteOrder"));
+  BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder",
                                           "()Ljava/nio/ByteOrder;"));
-  bailif0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid));
-  bailif0(cls = (*env)->GetObjectClass(env, bufobj));
-  bailif0(mid = (*env)->GetMethodID(env, cls, "order",
+  BAILIF0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid));
+  BAILIF0(cls = (*env)->GetObjectClass(env, bufobj));
+  BAILIF0(mid = (*env)->GetMethodID(env, cls, "order",
     "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
   (*env)->CallObjectMethod(env, bufobj, mid, borobj);
-  bailif0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer",
+  BAILIF0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer",
                                     "()Ljava/nio/ShortBuffer;"));
-  bailif0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid));
+  BAILIF0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid));
 
-  bailif0(cls = (*env)->FindClass(env, "java/awt/Rectangle"));
-  bailif0(arrayRegionObj = (*env)->AllocObject(env, cls));
-  bailif0(fid = (*env)->GetFieldID(env, cls, "x", "I"));
+  BAILIF0(cls = (*env)->FindClass(env, "java/awt/Rectangle"));
+  BAILIF0(arrayRegionObj = (*env)->AllocObject(env, cls));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I"));
   (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
   (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
   (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "height", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I"));
   (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
 
-  bailif0(planeRegionObj = (*env)->AllocObject(env, cls));
-  bailif0(fid = (*env)->GetFieldID(env, cls, "x", "I"));
+  BAILIF0(planeRegionObj = (*env)->AllocObject(env, cls));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I"));
   (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
   (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
   (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
-  bailif0(fid = (*env)->GetFieldID(env, cls, "height", "I"));
+  BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I"));
   (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
 
-  bailif0(cls = (*env)->GetObjectClass(env, cfobj));
-  bailif0(mid = (*env)->GetMethodID(env, cls, "customFilter",
+  BAILIF0(cls = (*env)->GetObjectClass(env, cfobj));
+  BAILIF0(mid = (*env)->GetMethodID(env, cls, "customFilter",
     "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
   (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
                          planeRegionObj, componentIndex, transformIndex, tobj);
@@ -1070,33 +1110,33 @@
   jint *dstSizesi = NULL;
   JNICustomFilterParams *params = NULL;
 
-  gethandle();
+  GET_HANDLE();
 
   if ((*env)->GetArrayLength(env, jsrcBuf) < jpegSize)
-    _throwarg("Source buffer is not large enough");
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
+    THROW_ARG("Source buffer is not large enough");
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
   jpegWidth = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
   jpegHeight = (int)(*env)->GetIntField(env, obj, _fid);
-  bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
+  BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
   jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid);
 
   n = (*env)->GetArrayLength(env, dstobjs);
   if (n != (*env)->GetArrayLength(env, tobjs))
-    _throwarg("Mismatch between size of transforms array and destination buffers array");
+    THROW_ARG("Mismatch between size of transforms array and destination buffers array");
 
   if ((dstBufs =
        (unsigned char **)malloc(sizeof(unsigned char *) * n)) == NULL)
-    _throwmem();
+    THROW_MEM();
   if ((jdstBufs = (jbyteArray *)malloc(sizeof(jbyteArray) * n)) == NULL)
-    _throwmem();
+    THROW_MEM();
   if ((dstSizes = (unsigned long *)malloc(sizeof(unsigned long) * n)) == NULL)
-    _throwmem();
+    THROW_MEM();
   if ((t = (tjtransform *)malloc(sizeof(tjtransform) * n)) == NULL)
-    _throwmem();
+    THROW_MEM();
   if ((params = (JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams) *
                                                 n)) == NULL)
-    _throwmem();
+    THROW_MEM();
   for (i = 0; i < n; i++) {
     dstBufs[i] = NULL;  jdstBufs[i] = NULL;  dstSizes[i] = 0;
     memset(&t[i], 0, sizeof(tjtransform));
@@ -1106,22 +1146,22 @@
   for (i = 0; i < n; i++) {
     jobject tobj, cfobj;
 
-    bailif0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i));
-    bailif0(_cls = (*env)->GetObjectClass(env, tobj));
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "op", "I"));
+    BAILIF0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i));
+    BAILIF0(_cls = (*env)->GetObjectClass(env, tobj));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "op", "I"));
     t[i].op = (*env)->GetIntField(env, tobj, _fid);
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "options", "I"));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "options", "I"));
     t[i].options = (*env)->GetIntField(env, tobj, _fid);
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "x", "I"));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "x", "I"));
     t[i].r.x = (*env)->GetIntField(env, tobj, _fid);
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "y", "I"));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "y", "I"));
     t[i].r.y = (*env)->GetIntField(env, tobj, _fid);
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "width", "I"));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "width", "I"));
     t[i].r.w = (*env)->GetIntField(env, tobj, _fid);
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "height", "I"));
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "height", "I"));
     t[i].r.h = (*env)->GetIntField(env, tobj, _fid);
 
-    bailif0(_fid = (*env)->GetFieldID(env, _cls, "cf",
+    BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "cf",
       "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
     cfobj = (*env)->GetObjectField(env, tobj, _fid);
     if (cfobj) {
@@ -1138,29 +1178,30 @@
 
     if (t[i].r.w != 0) w = t[i].r.w;
     if (t[i].r.h != 0) h = t[i].r.h;
-    bailif0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
+    BAILIF0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i));
     if ((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) <
         tjBufSize(w, h, jpegSubsamp))
-      _throwarg("Destination buffer is not large enough");
+      THROW_ARG("Destination buffer is not large enough");
   }
-  bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
+  BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
   for (i = 0; i < n; i++)
-    bailif0(dstBufs[i] =
+    BAILIF0(dstBufs[i] =
             (*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
 
   if (tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
-                  flags | TJFLAG_NOREALLOC) == -1)
-    _throwtj();
-
-  for (i = 0; i < n; i++) {
-    (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
-    dstBufs[i] = NULL;
+                  flags | TJFLAG_NOREALLOC) == -1) {
+    for (i = 0; i < n; i++)
+      SAFE_RELEASE(jdstBufs[i], dstBufs[i]);
+    SAFE_RELEASE(jsrcBuf, jpegBuf);
+    THROW_TJ();
   }
-  (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
-  jpegBuf = NULL;
+
+  for (i = 0; i < n; i++)
+    SAFE_RELEASE(jdstBufs[i], dstBufs[i]);
+  SAFE_RELEASE(jsrcBuf, jpegBuf);
 
   jdstSizes = (*env)->NewIntArray(env, n);
-  bailif0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0));
+  BAILIF0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0));
   for (i = 0; i < n; i++) dstSizesi[i] = (int)dstSizes[i];
 
 bailout:
@@ -1172,10 +1213,10 @@
     }
     free(dstBufs);
   }
-  if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
-  if (jdstBufs) free(jdstBufs);
-  if (dstSizes) free(dstSizes);
-  if (t) free(t);
+  SAFE_RELEASE(jsrcBuf, jpegBuf);
+  free(jdstBufs);
+  free(dstSizes);
+  free(t);
   return jdstSizes;
 }
 
diff --git a/src/third_party/libjpeg-turbo/turbojpeg-mapfile b/src/third_party/libjpeg-turbo/turbojpeg-mapfile
old mode 100755
new mode 100644
diff --git a/src/third_party/libjpeg-turbo/turbojpeg-mapfile.jni b/src/third_party/libjpeg-turbo/turbojpeg-mapfile.jni
old mode 100755
new mode 100644
diff --git a/src/third_party/libjpeg-turbo/turbojpeg.c b/src/third_party/libjpeg-turbo/turbojpeg.c
index 5a9f366..3dd0e6f 100644
--- a/src/third_party/libjpeg-turbo/turbojpeg.c
+++ b/src/third_party/libjpeg-turbo/turbojpeg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C)2009-2018 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2009-2021 D. R. Commander.  All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -56,18 +56,24 @@
 
 #include <ctype.h>
 
+#include "jconfigint.h"
+
 extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, unsigned long *,
                              boolean);
 extern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *,
                             unsigned long);
 
 #define PAD(v, p)  ((v + (p) - 1) & (~((p) - 1)))
-#define isPow2(x)  (((x) & (x - 1)) == 0)
+#define IS_POW2(x)  (((x) & (x - 1)) == 0)
 
 
 /* Error handling (based on example in example.txt) */
 
+#if defined(STARBOARD)
 static char errStr[JMSG_LENGTH_MAX] = "No error";
+#else
+static THREAD_LOCAL char errStr[JMSG_LENGTH_MAX] = "No error";
+#endif
 
 struct my_error_mgr {
   struct jpeg_error_mgr pub;
@@ -77,6 +83,12 @@
 };
 typedef struct my_error_mgr *my_error_ptr;
 
+#define JMESSAGE(code, string)  string,
+static const char *turbojpeg_message_table[] = {
+#include "cderror.h"
+  NULL
+};
+
 static void my_error_exit(j_common_ptr cinfo)
 {
   my_error_ptr myerr = (my_error_ptr)cinfo->err;
@@ -117,6 +129,32 @@
   boolean isInstanceError;
 } tjinstance;
 
+struct my_progress_mgr {
+  struct jpeg_progress_mgr pub;
+  tjinstance *this;
+};
+typedef struct my_progress_mgr *my_progress_ptr;
+
+static void my_progress_monitor(j_common_ptr dinfo)
+{
+  my_error_ptr myerr = (my_error_ptr)dinfo->err;
+  my_progress_ptr myprog = (my_progress_ptr)dinfo->progress;
+
+  if (dinfo->is_decompressor) {
+    int scan_no = ((j_decompress_ptr)dinfo)->input_scan_number;
+
+    if (scan_no > 500) {
+      snprintf(myprog->this->errStr, JMSG_LENGTH_MAX,
+               "Progressive JPEG image has more than 500 scans");
+      snprintf(errStr, JMSG_LENGTH_MAX,
+               "Progressive JPEG image has more than 500 scans");
+      myprog->this->isInstanceError = TRUE;
+      myerr->warning = FALSE;
+      longjmp(myerr->setjmp_buffer, 1);
+    }
+  }
+}
+
 static const int pixelsize[TJ_NUMSAMP] = { 3, 3, 3, 1, 3, 3 };
 
 static const JXFORM_CODE xformtypes[TJ_NUMXOP] = {
@@ -170,22 +208,27 @@
   TJPF_UNKNOWN
 };
 
-#define _throwg(m) { \
+#define THROWG(m) { \
   snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \
   retval = -1;  goto bailout; \
 }
-#define _throwunix(m) { \
+#define THROW_UNIX(m) { \
   char message[512]; \
   SbSystemGetErrorString(errno, message, SB_ARRAY_SIZE_INT(message)); \
   snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m, message); \
   retval = -1;  goto bailout; \
 }
-#define _throw(m) { \
+#define THROW(m) { \
   snprintf(this->errStr, JMSG_LENGTH_MAX, "%s", m); \
-  this->isInstanceError = TRUE;  _throwg(m) \
+  this->isInstanceError = TRUE;  THROWG(m) \
 }
 
-#define getinstance(handle) \
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+/* Private flag that triggers different TurboJPEG API behavior when fuzzing */
+#define TJFLAG_FUZZING  (1 << 30)
+#endif
+
+#define GET_INSTANCE(handle) \
   tjinstance *this = (tjinstance *)handle; \
   j_compress_ptr cinfo = NULL; \
   j_decompress_ptr dinfo = NULL; \
@@ -198,7 +241,7 @@
   this->jerr.warning = FALSE; \
   this->isInstanceError = FALSE;
 
-#define getcinstance(handle) \
+#define GET_CINSTANCE(handle) \
   tjinstance *this = (tjinstance *)handle; \
   j_compress_ptr cinfo = NULL; \
   \
@@ -210,7 +253,7 @@
   this->jerr.warning = FALSE; \
   this->isInstanceError = FALSE;
 
-#define getdinstance(handle) \
+#define GET_DINSTANCE(handle) \
   tjinstance *this = (tjinstance *)handle; \
   j_decompress_ptr dinfo = NULL; \
   \
@@ -241,11 +284,13 @@
   return -1;
 }
 
-static int setCompDefaults(struct jpeg_compress_struct *cinfo, int pixelFormat,
-                           int subsamp, int jpegQual, int flags)
+static void setCompDefaults(struct jpeg_compress_struct *cinfo,
+                            int pixelFormat, int subsamp, int jpegQual,
+                            int flags)
 {
-  int retval = 0;
+#ifndef NO_GETENV
   char *env = NULL;
+#endif
 
   cinfo->in_color_space = pf2cs[pixelFormat];
   cinfo->input_components = tjPixelSize[pixelFormat];
@@ -305,8 +350,6 @@
   cinfo->comp_info[2].v_samp_factor = 1;
   if (cinfo->num_components > 3)
     cinfo->comp_info[3].v_samp_factor = tjMCUHeight[subsamp] / 8;
-
-  return retval;
 }
 
 
@@ -367,6 +410,23 @@
           retval = i;  break;
         }
       }
+      /* Handle 4:4:4 images whose sampling factors are specified in
+         non-standard ways. */
+      if (dinfo->comp_info[0].h_samp_factor *
+          dinfo->comp_info[0].v_samp_factor <=
+          D_MAX_BLOCKS_IN_MCU / pixelsize[i] && i == TJSAMP_444) {
+        int match = 0;
+        for (k = 1; k < dinfo->num_components; k++) {
+          if (dinfo->comp_info[k].h_samp_factor ==
+              dinfo->comp_info[0].h_samp_factor &&
+              dinfo->comp_info[k].v_samp_factor ==
+              dinfo->comp_info[0].v_samp_factor)
+            match++;
+          if (match == dinfo->num_components - 1) {
+            retval = i;  break;
+          }
+        }
+      }
     }
   }
   return retval;
@@ -404,7 +464,7 @@
 
 DLLEXPORT int tjDestroy(tjhandle handle)
 {
-  getinstance(handle);
+  GET_INSTANCE(handle);
 
   if (setjmp(this->jerr.setjmp_buffer)) return -1;
   if (this->init & COMPRESS) jpeg_destroy_compress(cinfo);
@@ -421,7 +481,7 @@
 
 DLLEXPORT void tjFree(unsigned char *buf)
 {
-  if (buf) free(buf);
+  free(buf);
 }
 
 
@@ -445,10 +505,13 @@
   this->jerr.pub.output_message = my_output_message;
   this->jerr.emit_message = this->jerr.pub.emit_message;
   this->jerr.pub.emit_message = my_emit_message;
+  this->jerr.pub.addon_message_table = turbojpeg_message_table;
+  this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
+  this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
-    if (this) free(this);
+    free(this);
     return NULL;
   }
 
@@ -477,11 +540,11 @@
 
 DLLEXPORT unsigned long tjBufSize(int width, int height, int jpegSubsamp)
 {
-  unsigned long retval = 0;
+  unsigned long long retval = 0;
   int mcuw, mcuh, chromasf;
 
   if (width < 1 || height < 1 || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT)
-    _throwg("tjBufSize(): Invalid argument");
+    THROWG("tjBufSize(): Invalid argument");
 
   /* This allows for rare corner cases in which a JPEG image can actually be
      larger than the uncompressed input (we wouldn't mention it if it hadn't
@@ -489,36 +552,41 @@
   mcuw = tjMCUWidth[jpegSubsamp];
   mcuh = tjMCUHeight[jpegSubsamp];
   chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh);
-  retval = PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048;
+  retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL;
+  if (retval > (unsigned long long)((unsigned long)-1))
+    THROWG("tjBufSize(): Image is too large");
 
 bailout:
-  return retval;
+  return (unsigned long)retval;
 }
 
 DLLEXPORT unsigned long TJBUFSIZE(int width, int height)
 {
-  unsigned long retval = 0;
+  unsigned long long retval = 0;
 
   if (width < 1 || height < 1)
-    _throwg("TJBUFSIZE(): Invalid argument");
+    THROWG("TJBUFSIZE(): Invalid argument");
 
   /* This allows for rare corner cases in which a JPEG image can actually be
      larger than the uncompressed input (we wouldn't mention it if it hadn't
      happened before.) */
-  retval = PAD(width, 16) * PAD(height, 16) * 6 + 2048;
+  retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL;
+  if (retval > (unsigned long long)((unsigned long)-1))
+    THROWG("TJBUFSIZE(): Image is too large");
 
 bailout:
-  return retval;
+  return (unsigned long)retval;
 }
 
 
 DLLEXPORT unsigned long tjBufSizeYUV2(int width, int pad, int height,
                                       int subsamp)
 {
-  int retval = 0, nc, i;
+  unsigned long long retval = 0;
+  int nc, i;
 
   if (subsamp < 0 || subsamp >= NUMSUBOPT)
-    _throwg("tjBufSizeYUV2(): Invalid argument");
+    THROWG("tjBufSizeYUV2(): Invalid argument");
 
   nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
   for (i = 0; i < nc; i++) {
@@ -527,11 +595,13 @@
     int ph = tjPlaneHeight(i, height, subsamp);
 
     if (pw < 0 || ph < 0) return -1;
-    else retval += stride * ph;
+    else retval += (unsigned long long)stride * ph;
   }
+  if (retval > (unsigned long long)((unsigned long)-1))
+    THROWG("tjBufSizeYUV2(): Image is too large");
 
 bailout:
-  return retval;
+  return (unsigned long)retval;
 }
 
 DLLEXPORT unsigned long tjBufSizeYUV(int width, int height, int subsamp)
@@ -550,10 +620,10 @@
   int pw, nc, retval = 0;
 
   if (width < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP)
-    _throwg("tjPlaneWidth(): Invalid argument");
+    THROWG("tjPlaneWidth(): Invalid argument");
   nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
   if (componentID < 0 || componentID >= nc)
-    _throwg("tjPlaneWidth(): Invalid argument");
+    THROWG("tjPlaneWidth(): Invalid argument");
 
   pw = PAD(width, tjMCUWidth[subsamp] / 8);
   if (componentID == 0)
@@ -571,10 +641,10 @@
   int ph, nc, retval = 0;
 
   if (height < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP)
-    _throwg("tjPlaneHeight(): Invalid argument");
+    THROWG("tjPlaneHeight(): Invalid argument");
   nc = (subsamp == TJSAMP_GRAY ? 1 : 3);
   if (componentID < 0 || componentID >= nc)
-    _throwg("tjPlaneHeight(): Invalid argument");
+    THROWG("tjPlaneHeight(): Invalid argument");
 
   ph = PAD(height, tjMCUHeight[subsamp] / 8);
   if (componentID == 0)
@@ -590,11 +660,11 @@
 DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride,
                                        int height, int subsamp)
 {
-  unsigned long retval = 0;
+  unsigned long long retval = 0;
   int pw, ph;
 
   if (width < 1 || height < 1 || subsamp < 0 || subsamp >= NUMSUBOPT)
-    _throwg("tjPlaneSizeYUV(): Invalid argument");
+    THROWG("tjPlaneSizeYUV(): Invalid argument");
 
   pw = tjPlaneWidth(componentID, width, subsamp);
   ph = tjPlaneHeight(componentID, height, subsamp);
@@ -603,10 +673,12 @@
   if (stride == 0) stride = pw;
   else stride = abs(stride);
 
-  retval = stride * (ph - 1) + pw;
+  retval = (unsigned long long)stride * (ph - 1) + pw;
+  if (retval > (unsigned long long)((unsigned long)-1))
+    THROWG("tjPlaneSizeYUV(): Image is too large");
 
 bailout:
-  return retval;
+  return (unsigned long)retval;
 }
 
 
@@ -618,21 +690,21 @@
   int i, retval = 0, alloc = 1;
   JSAMPROW *row_pointer = NULL;
 
-  getcinstance(handle)
+  GET_CINSTANCE(handle)
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
   if ((this->init & COMPRESS) == 0)
-    _throw("tjCompress2(): Instance has not been initialized for compression");
+    THROW("tjCompress2(): Instance has not been initialized for compression");
 
   if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
       pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL ||
       jpegSize == NULL || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT ||
       jpegQual < 0 || jpegQual > 100)
-    _throw("tjCompress2(): Invalid argument");
+    THROW("tjCompress2(): Invalid argument");
 
   if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
 
   if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * height)) == NULL)
-    _throw("tjCompress2(): Memory allocation failure");
+    THROW("tjCompress2(): Memory allocation failure");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -652,15 +724,14 @@
     alloc = 0;  *jpegSize = tjBufSize(width, height, jpegSubsamp);
   }
   jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc);
-  if (setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags) == -1)
-    return -1;
+  setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual, flags);
 
   jpeg_start_compress(cinfo, TRUE);
   for (i = 0; i < height; i++) {
     if (flags & TJFLAG_BOTTOMUP)
-      row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch];
+      row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch];
     else
-      row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch];
+      row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch];
   }
   while (cinfo->next_scanline < cinfo->image_height)
     jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline],
@@ -668,8 +739,11 @@
   jpeg_finish_compress(cinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
-  if (row_pointer) free(row_pointer);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
+  }
+  free(row_pointer);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
   return retval;
@@ -711,7 +785,7 @@
   JSAMPLE *ptr;
   jpeg_component_info *compptr;
 
-  getcinstance(handle);
+  GET_CINSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
 
   for (i = 0; i < MAX_COMPONENTS; i++) {
@@ -720,17 +794,17 @@
   }
 
   if ((this->init & COMPRESS) == 0)
-    _throw("tjEncodeYUVPlanes(): Instance has not been initialized for compression");
+    THROW("tjEncodeYUVPlanes(): Instance has not been initialized for compression");
 
   if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
       pixelFormat < 0 || pixelFormat >= TJ_NUMPF || !dstPlanes ||
       !dstPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT)
-    _throw("tjEncodeYUVPlanes(): Invalid argument");
+    THROW("tjEncodeYUVPlanes(): Invalid argument");
   if (subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
-    _throw("tjEncodeYUVPlanes(): Invalid argument");
+    THROW("tjEncodeYUVPlanes(): Invalid argument");
 
   if (pixelFormat == TJPF_CMYK)
-    _throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
+    THROW("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
 
   if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
 
@@ -748,14 +822,14 @@
   else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
 #endif
 
-  if (setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags) == -1) return -1;
+  setCompDefaults(cinfo, pixelFormat, subsamp, -1, flags);
 
   /* Execute only the parts of jpeg_start_compress() that we need.  If we
      were to call the whole jpeg_start_compress() function, then it would try
      to write the file headers, which could overflow the output buffer if the
      YUV image were very small. */
   if (cinfo->global_state != CSTATE_START)
-    _throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state");
+    THROW("tjEncodeYUVPlanes(): libjpeg API is in the wrong state");
   (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo);
   jinit_c_master_control(cinfo, FALSE);
   jinit_color_converter(cinfo);
@@ -766,12 +840,12 @@
   ph0 = PAD(height, cinfo->max_v_samp_factor);
 
   if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL)
-    _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+    THROW("tjEncodeYUVPlanes(): Memory allocation failure");
   for (i = 0; i < height; i++) {
     if (flags & TJFLAG_BOTTOMUP)
-      row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch];
+      row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch];
     else
-      row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch];
+      row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch];
   }
   if (height < ph0)
     for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1];
@@ -783,11 +857,11 @@
           compptr->h_samp_factor, 32) *
       cinfo->max_v_samp_factor + 32);
     if (!_tmpbuf[i])
-      _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+      THROW("tjEncodeYUVPlanes(): Memory allocation failure");
     tmpbuf[i] =
       (JSAMPROW *)malloc(sizeof(JSAMPROW) * cinfo->max_v_samp_factor);
     if (!tmpbuf[i])
-      _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+      THROW("tjEncodeYUVPlanes(): Memory allocation failure");
     for (row = 0; row < cinfo->max_v_samp_factor; row++) {
       unsigned char *_tmpbuf_aligned =
         (unsigned char *)PAD((size_t)_tmpbuf[i], 32);
@@ -800,10 +874,10 @@
       (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) *
                         compptr->v_samp_factor + 32);
     if (!_tmpbuf2[i])
-      _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+      THROW("tjEncodeYUVPlanes(): Memory allocation failure");
     tmpbuf2[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor);
     if (!tmpbuf2[i])
-      _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+      THROW("tjEncodeYUVPlanes(): Memory allocation failure");
     for (row = 0; row < compptr->v_samp_factor; row++) {
       unsigned char *_tmpbuf2_aligned =
         (unsigned char *)PAD((size_t)_tmpbuf2[i], 32);
@@ -815,7 +889,7 @@
     ph[i] = ph0 * compptr->v_samp_factor / cinfo->max_v_samp_factor;
     outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]);
     if (!outbuf[i])
-      _throw("tjEncodeYUVPlanes(): Memory allocation failure");
+      THROW("tjEncodeYUVPlanes(): Memory allocation failure");
     ptr = dstPlanes[i];
     for (row = 0; row < ph[i]; row++) {
       outbuf[i][row] = ptr;
@@ -843,13 +917,13 @@
 
 bailout:
   if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
-  if (row_pointer) free(row_pointer);
+  free(row_pointer);
   for (i = 0; i < MAX_COMPONENTS; i++) {
-    if (tmpbuf[i] != NULL) free(tmpbuf[i]);
-    if (_tmpbuf[i] != NULL) free(_tmpbuf[i]);
-    if (tmpbuf2[i] != NULL) free(tmpbuf2[i]);
-    if (_tmpbuf2[i] != NULL) free(_tmpbuf2[i]);
-    if (outbuf[i] != NULL) free(outbuf[i]);
+    free(tmpbuf[i]);
+    free(_tmpbuf[i]);
+    free(tmpbuf2[i]);
+    free(_tmpbuf2[i]);
+    free(outbuf[i]);
   }
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
@@ -865,12 +939,12 @@
   int pw0, ph0, strides[3], retval = -1;
   tjinstance *this = (tjinstance *)handle;
 
-  if (!this) _throwg("tjEncodeYUV3(): Invalid handle");
+  if (!this) THROWG("tjEncodeYUV3(): Invalid handle");
   this->isInstanceError = FALSE;
 
-  if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 || !isPow2(pad) ||
-      subsamp < 0 || subsamp >= NUMSUBOPT)
-    _throw("tjEncodeYUV3(): Invalid argument");
+  if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 ||
+      !IS_POW2(pad) || subsamp < 0 || subsamp >= NUMSUBOPT)
+    THROW("tjEncodeYUV3(): Invalid argument");
 
   pw0 = tjPlaneWidth(0, width, subsamp);
   ph0 = tjPlaneHeight(0, height, subsamp);
@@ -927,7 +1001,7 @@
   JSAMPLE *_tmpbuf = NULL, *ptr;
   JSAMPROW *inbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS];
 
-  getcinstance(handle)
+  GET_CINSTANCE(handle)
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
 
   for (i = 0; i < MAX_COMPONENTS; i++) {
@@ -935,14 +1009,14 @@
   }
 
   if ((this->init & COMPRESS) == 0)
-    _throw("tjCompressFromYUVPlanes(): Instance has not been initialized for compression");
+    THROW("tjCompressFromYUVPlanes(): Instance has not been initialized for compression");
 
   if (!srcPlanes || !srcPlanes[0] || width <= 0 || height <= 0 ||
       subsamp < 0 || subsamp >= NUMSUBOPT || jpegBuf == NULL ||
       jpegSize == NULL || jpegQual < 0 || jpegQual > 100)
-    _throw("tjCompressFromYUVPlanes(): Invalid argument");
+    THROW("tjCompressFromYUVPlanes(): Invalid argument");
   if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
-    _throw("tjCompressFromYUVPlanes(): Invalid argument");
+    THROW("tjCompressFromYUVPlanes(): Invalid argument");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -962,8 +1036,7 @@
     alloc = 0;  *jpegSize = tjBufSize(width, height, subsamp);
   }
   jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc);
-  if (setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags) == -1)
-    return -1;
+  setCompDefaults(cinfo, TJPF_RGB, subsamp, jpegQual, flags);
   cinfo->raw_data_in = TRUE;
 
   jpeg_start_compress(cinfo, TRUE);
@@ -981,7 +1054,7 @@
     th[i] = compptr->v_samp_factor * DCTSIZE;
     tmpbufsize += iw[i] * th[i];
     if ((inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL)
-      _throw("tjCompressFromYUVPlanes(): Memory allocation failure");
+      THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
     ptr = (JSAMPLE *)srcPlanes[i];
     for (row = 0; row < ph[i]; row++) {
       inbuf[i][row] = ptr;
@@ -990,11 +1063,11 @@
   }
   if (usetmpbuf) {
     if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL)
-      _throw("tjCompressFromYUVPlanes(): Memory allocation failure");
+      THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
     ptr = _tmpbuf;
     for (i = 0; i < cinfo->num_components; i++) {
       if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL)
-        _throw("tjCompressFromYUVPlanes(): Memory allocation failure");
+        THROW("tjCompressFromYUVPlanes(): Memory allocation failure");
       for (row = 0; row < th[i]; row++) {
         tmpbuf[i][row] = ptr;
         ptr += iw[i];
@@ -1020,14 +1093,14 @@
         int j, k;
 
         for (j = 0; j < MIN(th[i], ph[i] - crow[i]); j++) {
-          MEMCOPY(tmpbuf[i][j], inbuf[i][crow[i] + j], pw[i]);
+          memcpy(tmpbuf[i][j], inbuf[i][crow[i] + j], pw[i]);
           /* Duplicate last sample in row to fill out MCU */
           for (k = pw[i]; k < iw[i]; k++)
             tmpbuf[i][j][k] = tmpbuf[i][j][pw[i] - 1];
         }
         /* Duplicate last row to fill out MCU */
         for (j = ph[i] - crow[i]; j < th[i]; j++)
-          MEMCOPY(tmpbuf[i][j], tmpbuf[i][ph[i] - crow[i] - 1], iw[i]);
+          memcpy(tmpbuf[i][j], tmpbuf[i][ph[i] - crow[i] - 1], iw[i]);
         yuvptr[i] = tmpbuf[i];
       } else
         yuvptr[i] = &inbuf[i][crow[i]];
@@ -1037,12 +1110,15 @@
   jpeg_finish_compress(cinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
-  for (i = 0; i < MAX_COMPONENTS; i++) {
-    if (tmpbuf[i]) free(tmpbuf[i]);
-    if (inbuf[i]) free(inbuf[i]);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
   }
-  if (_tmpbuf) free(_tmpbuf);
+  for (i = 0; i < MAX_COMPONENTS; i++) {
+    free(tmpbuf[i]);
+    free(inbuf[i]);
+  }
+  free(_tmpbuf);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
   return retval;
@@ -1058,12 +1134,12 @@
   int pw0, ph0, strides[3], retval = -1;
   tjinstance *this = (tjinstance *)handle;
 
-  if (!this) _throwg("tjCompressFromYUV(): Invalid handle");
+  if (!this) THROWG("tjCompressFromYUV(): Invalid handle");
   this->isInstanceError = FALSE;
 
   if (srcBuf == NULL || width <= 0 || pad < 1 || height <= 0 || subsamp < 0 ||
       subsamp >= NUMSUBOPT)
-    _throw("tjCompressFromYUV(): Invalid argument");
+    THROW("tjCompressFromYUV(): Invalid argument");
 
   pw0 = tjPlaneWidth(0, width, subsamp);
   ph0 = tjPlaneHeight(0, height, subsamp);
@@ -1101,10 +1177,13 @@
   this->jerr.pub.output_message = my_output_message;
   this->jerr.emit_message = this->jerr.pub.emit_message;
   this->jerr.pub.emit_message = my_emit_message;
+  this->jerr.pub.addon_message_table = turbojpeg_message_table;
+  this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE;
+  this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE;
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
-    if (this) free(this);
+    free(this);
     return NULL;
   }
 
@@ -1139,13 +1218,13 @@
 {
   int retval = 0;
 
-  getdinstance(handle);
+  GET_DINSTANCE(handle);
   if ((this->init & DECOMPRESS) == 0)
-    _throw("tjDecompressHeader3(): Instance has not been initialized for decompression");
+    THROW("tjDecompressHeader3(): Instance has not been initialized for decompression");
 
   if (jpegBuf == NULL || jpegSize <= 0 || width == NULL || height == NULL ||
       jpegSubsamp == NULL || jpegColorspace == NULL)
-    _throw("tjDecompressHeader3(): Invalid argument");
+    THROW("tjDecompressHeader3(): Invalid argument");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -1170,11 +1249,11 @@
   jpeg_abort_decompress(dinfo);
 
   if (*jpegSubsamp < 0)
-    _throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
+    THROW("tjDecompressHeader3(): Could not determine subsampling type for JPEG image");
   if (*jpegColorspace < 0)
-    _throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
+    THROW("tjDecompressHeader3(): Could not determine colorspace of JPEG image");
   if (*width < 1 || *height < 1)
-    _throw("tjDecompressHeader3(): Invalid data returned in header");
+    THROW("tjDecompressHeader3(): Invalid data returned in header");
 
 bailout:
   if (this->jerr.warning) retval = -1;
@@ -1222,15 +1301,16 @@
 {
   JSAMPROW *row_pointer = NULL;
   int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh;
+  struct my_progress_mgr progress;
 
-  getdinstance(handle);
+  GET_DINSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
   if ((this->init & DECOMPRESS) == 0)
-    _throw("tjDecompress2(): Instance has not been initialized for decompression");
+    THROW("tjDecompress2(): Instance has not been initialized for decompression");
 
   if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 ||
       pitch < 0 || height < 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
-    _throw("tjDecompress2(): Invalid argument");
+    THROW("tjDecompress2(): Invalid argument");
 
 #ifndef NO_PUTENV
   if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
@@ -1238,6 +1318,14 @@
   else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
 #endif
 
+  if (flags & TJFLAG_LIMITSCANS) {
+    MEMZERO(&progress, sizeof(struct my_progress_mgr));
+    progress.pub.progress_monitor = my_progress_monitor;
+    progress.this = this;
+    dinfo->progress = &progress.pub;
+  } else
+    dinfo->progress = NULL;
+
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
     retval = -1;  goto bailout;
@@ -1259,7 +1347,7 @@
       break;
   }
   if (i >= NUMSF)
-    _throw("tjDecompress2(): Could not scale down to desired image dimensions");
+    THROW("tjDecompress2(): Could not scale down to desired image dimensions");
   width = scaledw;  height = scaledh;
   dinfo->scale_num = sf[i].num;
   dinfo->scale_denom = sf[i].denom;
@@ -1269,16 +1357,16 @@
 
   if ((row_pointer =
        (JSAMPROW *)malloc(sizeof(JSAMPROW) * dinfo->output_height)) == NULL)
-    _throw("tjDecompress2(): Memory allocation failure");
+    THROW("tjDecompress2(): Memory allocation failure");
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
     retval = -1;  goto bailout;
   }
   for (i = 0; i < (int)dinfo->output_height; i++) {
     if (flags & TJFLAG_BOTTOMUP)
-      row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * pitch];
+      row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * (size_t)pitch];
     else
-      row_pointer[i] = &dstBuf[i * pitch];
+      row_pointer[i] = &dstBuf[i * (size_t)pitch];
   }
   while (dinfo->output_scanline < dinfo->output_height)
     jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline],
@@ -1287,7 +1375,7 @@
 
 bailout:
   if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
-  if (row_pointer) free(row_pointer);
+  free(row_pointer);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
   return retval;
@@ -1347,12 +1435,12 @@
 }
 
 
-int my_read_markers(j_decompress_ptr dinfo)
+static int my_read_markers(j_decompress_ptr dinfo)
 {
   return JPEG_REACHED_SOS;
 }
 
-void my_reset_marker_reader(j_decompress_ptr dinfo)
+static void my_reset_marker_reader(j_decompress_ptr dinfo)
 {
 }
 
@@ -1371,7 +1459,7 @@
   int (*old_read_markers) (j_decompress_ptr);
   void (*old_reset_marker_reader) (j_decompress_ptr);
 
-  getdinstance(handle);
+  GET_DINSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
 
   for (i = 0; i < MAX_COMPONENTS; i++) {
@@ -1379,14 +1467,14 @@
   }
 
   if ((this->init & DECOMPRESS) == 0)
-    _throw("tjDecodeYUVPlanes(): Instance has not been initialized for decompression");
+    THROW("tjDecodeYUVPlanes(): Instance has not been initialized for decompression");
 
   if (!srcPlanes || !srcPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT ||
       dstBuf == NULL || width <= 0 || pitch < 0 || height <= 0 ||
       pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
-    _throw("tjDecodeYUVPlanes(): Invalid argument");
+    THROW("tjDecodeYUVPlanes(): Invalid argument");
   if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2]))
-    _throw("tjDecodeYUVPlanes(): Invalid argument");
+    THROW("tjDecodeYUVPlanes(): Invalid argument");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -1394,7 +1482,7 @@
   }
 
   if (pixelFormat == TJPF_CMYK)
-    _throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels.");
+    THROW("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels.");
 
   if (pitch == 0) pitch = width * tjPixelSize[pixelFormat];
   dinfo->image_width = width;
@@ -1406,6 +1494,9 @@
   else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
 #endif
 
+  dinfo->progressive_mode = dinfo->inputctl->has_multiple_scans = FALSE;
+  dinfo->Ss = dinfo->Ah = dinfo->Al = 0;
+  dinfo->Se = DCTSIZE2 - 1;
   if (setDecodeDefaults(dinfo, pixelFormat, subsamp, flags) == -1) {
     retval = -1;  goto bailout;
   }
@@ -1430,12 +1521,12 @@
   if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat];
 
   if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL)
-    _throw("tjDecodeYUVPlanes(): Memory allocation failure");
+    THROW("tjDecodeYUVPlanes(): Memory allocation failure");
   for (i = 0; i < height; i++) {
     if (flags & TJFLAG_BOTTOMUP)
-      row_pointer[i] = &dstBuf[(height - i - 1) * pitch];
+      row_pointer[i] = &dstBuf[(height - i - 1) * (size_t)pitch];
     else
-      row_pointer[i] = &dstBuf[i * pitch];
+      row_pointer[i] = &dstBuf[i * (size_t)pitch];
   }
   if (height < ph0)
     for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1];
@@ -1446,10 +1537,10 @@
       (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) *
                         compptr->v_samp_factor + 32);
     if (!_tmpbuf[i])
-      _throw("tjDecodeYUVPlanes(): Memory allocation failure");
+      THROW("tjDecodeYUVPlanes(): Memory allocation failure");
     tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor);
     if (!tmpbuf[i])
-      _throw("tjDecodeYUVPlanes(): Memory allocation failure");
+      THROW("tjDecodeYUVPlanes(): Memory allocation failure");
     for (row = 0; row < compptr->v_samp_factor; row++) {
       unsigned char *_tmpbuf_aligned =
         (unsigned char *)PAD((size_t)_tmpbuf[i], 32);
@@ -1461,7 +1552,7 @@
     ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor;
     inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]);
     if (!inbuf[i])
-      _throw("tjDecodeYUVPlanes(): Memory allocation failure");
+      THROW("tjDecodeYUVPlanes(): Memory allocation failure");
     ptr = (JSAMPLE *)srcPlanes[i];
     for (row = 0; row < ph[i]; row++) {
       inbuf[i][row] = ptr;
@@ -1490,11 +1581,11 @@
 
 bailout:
   if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
-  if (row_pointer) free(row_pointer);
+  free(row_pointer);
   for (i = 0; i < MAX_COMPONENTS; i++) {
-    if (tmpbuf[i] != NULL) free(tmpbuf[i]);
-    if (_tmpbuf[i] != NULL) free(_tmpbuf[i]);
-    if (inbuf[i] != NULL) free(inbuf[i]);
+    free(tmpbuf[i]);
+    free(_tmpbuf[i]);
+    free(inbuf[i]);
   }
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
@@ -1510,12 +1601,12 @@
   int pw0, ph0, strides[3], retval = -1;
   tjinstance *this = (tjinstance *)handle;
 
-  if (!this) _throwg("tjDecodeYUV(): Invalid handle");
+  if (!this) THROWG("tjDecodeYUV(): Invalid handle");
   this->isInstanceError = FALSE;
 
-  if (srcBuf == NULL || pad < 0 || !isPow2(pad) || subsamp < 0 ||
+  if (srcBuf == NULL || pad < 0 || !IS_POW2(pad) || subsamp < 0 ||
       subsamp >= NUMSUBOPT || width <= 0 || height <= 0)
-    _throw("tjDecodeYUV(): Invalid argument");
+    THROW("tjDecodeYUV(): Invalid argument");
 
   pw0 = tjPlaneWidth(0, width, subsamp);
   ph0 = tjPlaneHeight(0, height, subsamp);
@@ -1553,8 +1644,9 @@
   JSAMPLE *_tmpbuf = NULL, *ptr;
   JSAMPROW *outbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS];
   int dctsize;
+  struct my_progress_mgr progress;
 
-  getdinstance(handle);
+  GET_DINSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
 
   for (i = 0; i < MAX_COMPONENTS; i++) {
@@ -1562,11 +1654,11 @@
   }
 
   if ((this->init & DECOMPRESS) == 0)
-    _throw("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression");
+    THROW("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression");
 
   if (jpegBuf == NULL || jpegSize <= 0 || !dstPlanes || !dstPlanes[0] ||
       width < 0 || height < 0)
-    _throw("tjDecompressToYUVPlanes(): Invalid argument");
+    THROW("tjDecompressToYUVPlanes(): Invalid argument");
 
 #ifndef NO_PUTENV
   if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
@@ -1574,6 +1666,14 @@
   else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
 #endif
 
+  if (flags & TJFLAG_LIMITSCANS) {
+    MEMZERO(&progress, sizeof(struct my_progress_mgr));
+    progress.pub.progress_monitor = my_progress_monitor;
+    progress.this = this;
+    dinfo->progress = &progress.pub;
+  } else
+    dinfo->progress = NULL;
+
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
     retval = -1;  goto bailout;
@@ -1586,10 +1686,10 @@
   this->headerRead = 0;
   jpegSubsamp = getSubsamp(dinfo);
   if (jpegSubsamp < 0)
-    _throw("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image");
+    THROW("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image");
 
   if (jpegSubsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
-    _throw("tjDecompressToYUVPlanes(): Invalid argument");
+    THROW("tjDecompressToYUVPlanes(): Invalid argument");
 
   jpegwidth = dinfo->image_width;  jpegheight = dinfo->image_height;
   if (width == 0) width = jpegwidth;
@@ -1601,9 +1701,9 @@
       break;
   }
   if (i >= NUMSF)
-    _throw("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions");
+    THROW("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions");
   if (dinfo->num_components > 3)
-    _throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components");
+    THROW("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components");
 
   width = scaledw;  height = scaledh;
   dinfo->scale_num = sf[i].num;
@@ -1619,15 +1719,13 @@
 
     iw[i] = compptr->width_in_blocks * dctsize;
     ih = compptr->height_in_blocks * dctsize;
-    pw[i] = PAD(dinfo->output_width, dinfo->max_h_samp_factor) *
-            compptr->h_samp_factor / dinfo->max_h_samp_factor;
-    ph[i] = PAD(dinfo->output_height, dinfo->max_v_samp_factor) *
-            compptr->v_samp_factor / dinfo->max_v_samp_factor;
+    pw[i] = tjPlaneWidth(i, dinfo->output_width, jpegSubsamp);
+    ph[i] = tjPlaneHeight(i, dinfo->output_height, jpegSubsamp);
     if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1;
     th[i] = compptr->v_samp_factor * dctsize;
     tmpbufsize += iw[i] * th[i];
     if ((outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL)
-      _throw("tjDecompressToYUVPlanes(): Memory allocation failure");
+      THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
     ptr = dstPlanes[i];
     for (row = 0; row < ph[i]; row++) {
       outbuf[i][row] = ptr;
@@ -1636,11 +1734,11 @@
   }
   if (usetmpbuf) {
     if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL)
-      _throw("tjDecompressToYUVPlanes(): Memory allocation failure");
+      THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
     ptr = _tmpbuf;
     for (i = 0; i < dinfo->num_components; i++) {
       if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL)
-        _throw("tjDecompressToYUVPlanes(): Memory allocation failure");
+        THROW("tjDecompressToYUVPlanes(): Memory allocation failure");
       for (row = 0; row < th[i]; row++) {
         tmpbuf[i][row] = ptr;
         ptr += iw[i];
@@ -1694,7 +1792,7 @@
 
       for (i = 0; i < dinfo->num_components; i++) {
         for (j = 0; j < MIN(th[i], ph[i] - crow[i]); j++) {
-          MEMCOPY(outbuf[i][crow[i] + j], tmpbuf[i][j], pw[i]);
+          memcpy(outbuf[i][crow[i] + j], tmpbuf[i][j], pw[i]);
         }
       }
     }
@@ -1704,10 +1802,10 @@
 bailout:
   if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
   for (i = 0; i < MAX_COMPONENTS; i++) {
-    if (tmpbuf[i]) free(tmpbuf[i]);
-    if (outbuf[i]) free(outbuf[i]);
+    free(tmpbuf[i]);
+    free(outbuf[i]);
   }
-  if (_tmpbuf) free(_tmpbuf);
+  free(_tmpbuf);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
   return retval;
@@ -1721,12 +1819,12 @@
   int pw0, ph0, strides[3], retval = -1, jpegSubsamp = -1;
   int i, jpegwidth, jpegheight, scaledw, scaledh;
 
-  getdinstance(handle);
+  GET_DINSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
 
   if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 ||
-      pad < 1 || !isPow2(pad) || height < 0)
-    _throw("tjDecompressToYUV2(): Invalid argument");
+      pad < 1 || !IS_POW2(pad) || height < 0)
+    THROW("tjDecompressToYUV2(): Invalid argument");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -1737,7 +1835,7 @@
   jpeg_read_header(dinfo, TRUE);
   jpegSubsamp = getSubsamp(dinfo);
   if (jpegSubsamp < 0)
-    _throw("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image");
+    THROW("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image");
 
   jpegwidth = dinfo->image_width;  jpegheight = dinfo->image_height;
   if (width == 0) width = jpegwidth;
@@ -1750,7 +1848,7 @@
       break;
   }
   if (i >= NUMSF)
-    _throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
+    THROW("tjDecompressToYUV2(): Could not scale down to desired image dimensions");
 
   pw0 = tjPlaneWidth(0, width, jpegSubsamp);
   ph0 = tjPlaneHeight(0, height, jpegSubsamp);
@@ -1813,16 +1911,17 @@
 {
   jpeg_transform_info *xinfo = NULL;
   jvirt_barray_ptr *srccoefs, *dstcoefs;
-  int retval = 0, i, jpegSubsamp, saveMarkers = 0;
+  int retval = 0, alloc = 1, i, jpegSubsamp, saveMarkers = 0;
+  struct my_progress_mgr progress;
 
-  getinstance(handle);
+  GET_INSTANCE(handle);
   this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE;
   if ((this->init & COMPRESS) == 0 || (this->init & DECOMPRESS) == 0)
-    _throw("tjTransform(): Instance has not been initialized for transformation");
+    THROW("tjTransform(): Instance has not been initialized for transformation");
 
   if (jpegBuf == NULL || jpegSize <= 0 || n < 1 || dstBufs == NULL ||
       dstSizes == NULL || t == NULL || flags < 0)
-    _throw("tjTransform(): Invalid argument");
+    THROW("tjTransform(): Invalid argument");
 
 #ifndef NO_PUTENV
   if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
@@ -1830,9 +1929,17 @@
   else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
 #endif
 
+  if (flags & TJFLAG_LIMITSCANS) {
+    MEMZERO(&progress, sizeof(struct my_progress_mgr));
+    progress.pub.progress_monitor = my_progress_monitor;
+    progress.this = this;
+    dinfo->progress = &progress.pub;
+  } else
+    dinfo->progress = NULL;
+
   if ((xinfo =
        (jpeg_transform_info *)malloc(sizeof(jpeg_transform_info) * n)) == NULL)
-    _throw("tjTransform(): Memory allocation failure");
+    THROW("tjTransform(): Memory allocation failure");
   MEMZERO(xinfo, sizeof(jpeg_transform_info) * n);
 
   if (setjmp(this->jerr.setjmp_buffer)) {
@@ -1870,19 +1977,20 @@
   jpeg_read_header(dinfo, TRUE);
   jpegSubsamp = getSubsamp(dinfo);
   if (jpegSubsamp < 0)
-    _throw("tjTransform(): Could not determine subsampling type for JPEG image");
+    THROW("tjTransform(): Could not determine subsampling type for JPEG image");
 
   for (i = 0; i < n; i++) {
     if (!jtransform_request_workspace(dinfo, &xinfo[i]))
-      _throw("tjTransform(): Transform is not perfect");
+      THROW("tjTransform(): Transform is not perfect");
 
     if (xinfo[i].crop) {
       if ((t[i].r.x % xinfo[i].iMCU_sample_width) != 0 ||
           (t[i].r.y % xinfo[i].iMCU_sample_height) != 0) {
-        snprintf(errStr, JMSG_LENGTH_MAX,
+        snprintf(this->errStr, JMSG_LENGTH_MAX,
                  "To crop this JPEG image, x must be a multiple of %d\n"
                  "and y must be a multiple of %d.\n",
                  xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height);
+        this->isInstanceError = TRUE;
         retval = -1;  goto bailout;
       }
     }
@@ -1891,7 +1999,7 @@
   srccoefs = jpeg_read_coefficients(dinfo);
 
   for (i = 0; i < n; i++) {
-    int w, h, alloc = 1;
+    int w, h;
 
     if (!xinfo[i].crop) {
       w = dinfo->image_width;  h = dinfo->image_height;
@@ -1937,7 +2045,7 @@
           for (y = 0; y < compptr->v_samp_factor; y++) {
             if (t[i].customFilter(barray[y][0], arrayRegion, planeRegion, ci,
                                   i, &t[i]) == -1)
-              _throw("tjTransform(): Error in custom filter");
+              THROW("tjTransform(): Error in custom filter");
             arrayRegion.y += DCTSIZE;
           }
         }
@@ -1949,9 +2057,12 @@
   jpeg_finish_decompress(dinfo);
 
 bailout:
-  if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo);
+  if (cinfo->global_state > CSTATE_START) {
+    if (alloc) (*cinfo->dest->term_destination) (cinfo);
+    jpeg_abort_compress(cinfo);
+  }
   if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo);
-  if (xinfo) free(xinfo);
+  free(xinfo);
   if (this->jerr.warning) retval = -1;
   this->jerr.stopOnWarning = FALSE;
   return retval;
@@ -1963,7 +2074,8 @@
                                      int align, int *height, int *pixelFormat,
                                      int flags)
 {
-  int retval = 0, tempc, pitch;
+  int retval = 0, tempc;
+  size_t pitch;
   tjhandle handle = NULL;
   tjinstance *this;
   j_compress_ptr cinfo = NULL;
@@ -1974,21 +2086,21 @@
 
   if (!filename || !width || align < 1 || !height || !pixelFormat ||
       *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF)
-    _throwg("tjLoadImage(): Invalid argument");
+    THROWG("tjLoadImage(): Invalid argument");
   if ((align & (align - 1)) != 0)
-    _throwg("tjLoadImage(): Alignment must be a power of 2");
+    THROWG("tjLoadImage(): Alignment must be a power of 2");
 
   if ((handle = tjInitCompress()) == NULL) return NULL;
   this = (tjinstance *)handle;
   cinfo = &this->cinfo;
 
   if ((file = fopen(filename, "rb")) == NULL)
-    _throwunix("tjLoadImage(): Cannot open input file");
+    THROW_UNIX("tjLoadImage(): Cannot open input file");
 
   if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF)
-    _throwunix("tjLoadImage(): Could not read input file")
+    THROW_UNIX("tjLoadImage(): Could not read input file")
   else if (tempc == EOF)
-    _throwg("tjLoadImage(): Input file contains no data");
+    THROWG("tjLoadImage(): Input file contains no data");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -1999,16 +2111,21 @@
   else cinfo->in_color_space = pf2cs[*pixelFormat];
   if (tempc == 'B') {
     if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL)
-      _throwg("tjLoadImage(): Could not initialize bitmap loader");
+      THROWG("tjLoadImage(): Could not initialize bitmap loader");
     invert = (flags & TJFLAG_BOTTOMUP) == 0;
   } else if (tempc == 'P') {
     if ((src = jinit_read_ppm(cinfo)) == NULL)
-      _throwg("tjLoadImage(): Could not initialize bitmap loader");
+      THROWG("tjLoadImage(): Could not initialize bitmap loader");
     invert = (flags & TJFLAG_BOTTOMUP) != 0;
   } else
-    _throwg("tjLoadImage(): Unsupported file type");
+    THROWG("tjLoadImage(): Unsupported file type");
 
   src->input_file = file;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+  /* Refuse to load images larger than 1 Megapixel when fuzzing. */
+  if (flags & TJFLAG_FUZZING)
+    src->max_pixels = 1048576;
+#endif
   (*src->start_input) (cinfo, src);
   (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo);
 
@@ -2016,8 +2133,10 @@
   *pixelFormat = cs2pf[cinfo->in_color_space];
 
   pitch = PAD((*width) * tjPixelSize[*pixelFormat], align);
-  if ((dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL)
-    _throwg("tjLoadImage(): Memory allocation failure");
+  if ((unsigned long long)pitch * (unsigned long long)(*height) >
+      (unsigned long long)((size_t)-1) ||
+      (dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL)
+    THROWG("tjLoadImage(): Memory allocation failure");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -2044,7 +2163,7 @@
 bailout:
   if (handle) tjDestroy(handle);
   if (file) fclose(file);
-  if (retval < 0 && dstBuf) { free(dstBuf);  dstBuf = NULL; }
+  if (retval < 0) { free(dstBuf);  dstBuf = NULL; }
   return dstBuf;
 }
 #endif
@@ -2066,7 +2185,7 @@
 
   if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 ||
       pixelFormat < 0 || pixelFormat >= TJ_NUMPF)
-    _throwg("tjSaveImage(): Invalid argument");
+    THROWG("tjSaveImage(): Invalid argument");
 
   if ((handle = tjInitDecompress()) == NULL)
     return -1;
@@ -2074,7 +2193,7 @@
   dinfo = &this->dinfo;
 
   if ((file = fopen(filename, "wb")) == NULL)
-    _throwunix("tjSaveImage(): Cannot open output file");
+    THROW_UNIX("tjSaveImage(): Cannot open output file");
 
   if (setjmp(this->jerr.setjmp_buffer)) {
     /* If we get here, the JPEG code has signaled an error. */
@@ -2089,11 +2208,11 @@
   ptr = strrchr(filename, '.');
   if (ptr && !strcasecmp(ptr, ".bmp")) {
     if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL)
-      _throwg("tjSaveImage(): Could not initialize bitmap writer");
+      THROWG("tjSaveImage(): Could not initialize bitmap writer");
     invert = (flags & TJFLAG_BOTTOMUP) == 0;
   } else {
     if ((dst = jinit_write_ppm(dinfo)) == NULL)
-      _throwg("tjSaveImage(): Could not initialize PPM writer");
+      THROWG("tjSaveImage(): Could not initialize PPM writer");
     invert = (flags & TJFLAG_BOTTOMUP) != 0;
   }
 
diff --git a/src/third_party/libjpeg-turbo/turbojpeg.h b/src/third_party/libjpeg-turbo/turbojpeg.h
index 3be2e96..a7e120f 100644
--- a/src/third_party/libjpeg-turbo/turbojpeg.h
+++ b/src/third_party/libjpeg-turbo/turbojpeg.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C)2009-2015, 2017 D. R. Commander.  All Rights Reserved.
+ * Copyright (C)2009-2015, 2017, 2020-2021 D. R. Commander.
+ *                                         All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -418,6 +419,16 @@
  * reduce compression and decompression performance considerably.
  */
 #define TJFLAG_PROGRESSIVE  16384
+/**
+ * Limit the number of progressive JPEG scans that the decompression and
+ * transform functions will process.  If a progressive JPEG image contains an
+ * unreasonably large number of scans, then this flag will cause the
+ * decompression and transform functions to return an error.  The primary
+ * purpose of this is to allow security-critical applications to guard against
+ * an exploit of the progressive JPEG format described in
+ * <a href="https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf" target="_blank">this report</a>.
+ */
+#define TJFLAG_LIMITSCANS  32768
 
 
 /**
@@ -1640,7 +1651,8 @@
  * (re)allocated by the compression and transform functions or that were
  * manually allocated using #tjAlloc().
  *
- * @param buffer address of the buffer to free
+ * @param buffer address of the buffer to free.  If the address is NULL, then
+ * this function has no effect.
  *
  * @sa tjAlloc()
  */
@@ -1653,7 +1665,7 @@
  * @param handle a handle to a TurboJPEG compressor, decompressor, or
  * transformer instance, or NULL if the error was generated by a global
  * function (but note that retrieving the error message for a global function
- * is not thread-safe.)
+ * is thread-safe only on platforms that support thread-local storage.)
  *
  * @return a descriptive error message explaining why the last command failed.
  */
diff --git a/src/third_party/libjpeg-turbo/usage.txt b/src/third_party/libjpeg-turbo/usage.txt
index 3cbdb53..f7fa3c0 100644
--- a/src/third_party/libjpeg-turbo/usage.txt
+++ b/src/third_party/libjpeg-turbo/usage.txt
@@ -50,11 +50,9 @@
 This syntax works on all systems, so it is useful for scripts.
 
 The currently supported image file formats are: PPM (PBMPLUS color format),
-PGM (PBMPLUS grayscale format), BMP, Targa, and RLE (Utah Raster Toolkit
-format).  (RLE is supported only if the URT library is available, which it
-isn't on most non-Unix systems.)  cjpeg recognizes the input image format
-automatically, with the exception of some Targa files.  You have to tell djpeg
-which format to generate.
+PGM (PBMPLUS grayscale format), BMP, GIF, and Targa.  cjpeg recognizes the
+input image format automatically, with the exception of some Targa files.  You
+have to tell djpeg which format to generate.
 
 JPEG files are in the defacto standard JFIF file format.  There are other,
 less widely used JPEG-based file formats, but we don't support them.
@@ -76,10 +74,10 @@
 
         -grayscale      Create monochrome JPEG file from color input.
                         Be sure to use this switch when compressing a grayscale
-                        BMP file, because cjpeg isn't bright enough to notice
-                        whether a BMP file uses only shades of gray.  By
-                        saying -grayscale, you'll get a smaller JPEG file that
-                        takes less time to process.
+                        BMP or GIF file, because cjpeg isn't bright enough to
+                        notice whether a BMP or GIF file uses only shades of
+                        gray.  By saying -grayscale, you'll get a smaller JPEG
+                        file that takes less time to process.
 
         -rgb            Create RGB JPEG file.
                         Using this switch suppresses the conversion from RGB
@@ -170,35 +168,43 @@
                         be unable to view an arithmetic coded JPEG file at
                         all.
 
-        -dct int        Use integer DCT method (default).
-        -dct fast       Use fast integer DCT (less accurate).
-                        In libjpeg-turbo, the fast method is generally about
-                        5-15% faster than the int method when using the
-                        x86/x86-64 SIMD extensions (results may vary with other
-                        SIMD implementations, or when using libjpeg-turbo
-                        without SIMD extensions.)  For quality levels of 90 and
-                        below, there should be little or no perceptible
-                        difference between the two algorithms.  For quality
-                        levels above 90, however, the difference between
-                        the fast and the int methods becomes more pronounced.
-                        With quality=97, for instance, the fast method incurs
-                        generally about a 1-3 dB loss (in PSNR) relative to
-                        the int method, but this can be larger for some images.
-                        Do not use the fast method with quality levels above
-                        97.  The algorithm often degenerates at quality=98 and
-                        above and can actually produce a more lossy image than
-                        if lower quality levels had been used.  Also, in
-                        libjpeg-turbo, the fast method is not fully accerated
-                        for quality levels above 97, so it will be slower than
-                        the int method.
-        -dct float      Use floating-point DCT method.
-                        The float method is mainly a legacy feature.  It does
-                        not produce significantly more accurate results than
-                        the int method, and it is much slower.  The float
-                        method may also give different results on different
-                        machines due to varying roundoff behavior, whereas the
-                        integer methods should give the same results on all
-                        machines.
+        -dct int        Use accurate integer DCT method (default).
+        -dct fast       Use less accurate integer DCT method [legacy feature].
+                        When the Independent JPEG Group's software was first
+                        released in 1991, the compression time for a
+                        1-megapixel JPEG image on a mainstream PC was measured
+                        in minutes.  Thus, the fast integer DCT algorithm
+                        provided noticeable performance benefits.  On modern
+                        CPUs running libjpeg-turbo, however, the compression
+                        time for a 1-megapixel JPEG image is measured in
+                        milliseconds, and thus the performance benefits of the
+                        fast algorithm are much less noticeable.  On modern
+                        x86/x86-64 CPUs that support AVX2 instructions, the
+                        fast and int methods have similar performance.  On
+                        other types of CPUs, the fast method is generally about
+                        5-15% faster than the int method.
+
+                        For quality levels of 90 and below, there should be
+                        little or no perceptible quality difference between the
+                        two algorithms.  For quality levels above 90, however,
+                        the difference between the fast and int methods becomes
+                        more pronounced.  With quality=97, for instance, the
+                        fast method incurs generally about a 1-3 dB loss in
+                        PSNR relative to the int method, but this can be larger
+                        for some images.  Do not use the fast method with
+                        quality levels above 97.  The algorithm often
+                        degenerates at quality=98 and above and can actually
+                        produce a more lossy image than if lower quality levels
+                        had been used.  Also, in libjpeg-turbo, the fast method
+                        is not fully accelerated for quality levels above 97,
+                        so it will be slower than the int method.
+        -dct float      Use floating-point DCT method [legacy feature].
+                        The float method does not produce significantly more
+                        accurate results than the int method, and it is much
+                        slower.  The float method may also give different
+                        results on different machines due to varying roundoff
+                        behavior, whereas the integer methods should give the
+                        same results on all machines.
 
         -restart N      Emit a JPEG restart marker every N MCU rows, or every
                         N MCU blocks if "B" is attached to the number.
@@ -290,10 +296,17 @@
                         is specified, or if the JPEG file is grayscale;
                         otherwise, 24-bit full-color format is emitted.
 
-        -gif            Select GIF output format.  Since GIF does not support
-                        more than 256 colors, -colors 256 is assumed (unless
-                        you specify a smaller number of colors).  If you
-                        specify -fast, the default number of colors is 216.
+        -gif            Select GIF output format (LZW-compressed).  Since GIF
+                        does not support more than 256 colors, -colors 256 is
+                        assumed (unless you specify a smaller number of
+                        colors).  If you specify -fast, the default number of
+                        colors is 216.
+
+        -gif0           Select GIF output format (uncompressed).  Since GIF
+                        does not support more than 256 colors, -colors 256 is
+                        assumed (unless you specify a smaller number of
+                        colors).  If you specify -fast, the default number of
+                        colors is 216.
 
         -os2            Select BMP output format (OS/2 1.x flavor).  8-bit
                         colormapped format is emitted if -colors or -grayscale
@@ -305,8 +318,6 @@
                         grayscale or if -grayscale is specified; otherwise
                         PPM is emitted.
 
-        -rle            Select RLE output format.  (Requires URT library.)
-
         -targa          Select Targa output format.  Grayscale format is
                         emitted if the JPEG file is grayscale or if
                         -grayscale is specified; otherwise, colormapped format
@@ -315,36 +326,45 @@
 
 Switches for advanced users:
 
-        -dct int        Use integer DCT method (default).
-        -dct fast       Use fast integer DCT (less accurate).
-                        In libjpeg-turbo, the fast method is generally about
-                        5-15% faster than the int method when using the
-                        x86/x86-64 SIMD extensions (results may vary with other
-                        SIMD implementations, or when using libjpeg-turbo
-                        without SIMD extensions.)  If the JPEG image was
-                        compressed using a quality level of 85 or below, then
-                        there should be little or no perceptible difference
-                        between the two algorithms.  When decompressing images
-                        that were compressed using quality levels above 85,
-                        however, the difference between the fast and int
-                        methods becomes more pronounced.  With images
-                        compressed using quality=97, for instance, the fast
-                        method incurs generally about a 4-6 dB loss (in PSNR)
-                        relative to the int method, but this can be larger for
-                        some images.  If you can avoid it, do not use the fast
-                        method when decompressing images that were compressed
-                        using quality levels above 97.  The algorithm often
-                        degenerates for such images and can actually produce
-                        a more lossy output image than if the JPEG image had
-                        been compressed using lower quality levels.
-        -dct float      Use floating-point DCT method.
-                        The float method is mainly a legacy feature.  It does
-                        not produce significantly more accurate results than
-                        the int method, and it is much slower.  The float
-                        method may also give different results on different
-                        machines due to varying roundoff behavior, whereas the
-                        integer methods should give the same results on all
-                        machines.
+        -dct int        Use accurate integer DCT method (default).
+        -dct fast       Use less accurate integer DCT method [legacy feature].
+                        When the Independent JPEG Group's software was first
+                        released in 1991, the decompression time for a
+                        1-megapixel JPEG image on a mainstream PC was measured
+                        in minutes.  Thus, the fast integer DCT algorithm
+                        provided noticeable performance benefits.  On modern
+                        CPUs running libjpeg-turbo, however, the decompression
+                        time for a 1-megapixel JPEG image is measured in
+                        milliseconds, and thus the performance benefits of the
+                        fast algorithm are much less noticeable.  On modern
+                        x86/x86-64 CPUs that support AVX2 instructions, the
+                        fast and int methods have similar performance.  On
+                        other types of CPUs, the fast method is generally about
+                        5-15% faster than the int method.
+
+                        If the JPEG image was compressed using a quality level
+                        of 85 or below, then there should be little or no
+                        perceptible quality difference between the two
+                        algorithms.  When decompressing images that were
+                        compressed using quality levels above 85, however, the
+                        difference between the fast and int methods becomes
+                        more pronounced.  With images compressed using
+                        quality=97, for instance, the fast method incurs
+                        generally about a 4-6 dB loss in PSNR relative to the
+                        int method, but this can be larger for some images.  If
+                        you can avoid it, do not use the fast method when
+                        decompressing images that were compressed using quality
+                        levels above 97.  The algorithm often degenerates for
+                        such images and can actually produce a more lossy
+                        output image than if the JPEG image had been compressed
+                        using lower quality levels.
+        -dct float      Use floating-point DCT method [legacy feature].
+                        The float method does not produce significantly more
+                        accurate results than the int method, and it is much
+                        slower.  The float method may also give different
+                        results on different machines due to varying roundoff
+                        behavior, whereas the integer methods should give the
+                        same results on all machines.
 
         -dither fs      Use Floyd-Steinberg dithering in color quantization.
         -dither ordered Use ordered dithering in color quantization.
@@ -404,11 +424,6 @@
 is often a lot more than it is on larger files.  (At present, -optimize
 mode is always selected when generating progressive JPEG files.)
 
-Support for GIF input files was removed in cjpeg v6b due to concerns over
-the Unisys LZW patent.  Although this patent expired in 2006, cjpeg still
-lacks GIF support, for these historical reasons.  (Conversion of GIF files to
-JPEG is usually a bad idea anyway.)
-
 
 HINTS FOR DJPEG
 
@@ -423,10 +438,6 @@
 much lower quality than the default behavior.  "-dither none" may give
 acceptable results in two-pass mode, but is seldom tolerable in one-pass mode.
 
-To avoid the Unisys LZW patent (now expired), djpeg produces uncompressed GIF
-files.  These are larger than they should be, but are readable by standard GIF
-decoders.
-
 
 HINTS FOR BOTH PROGRAMS
 
@@ -533,6 +544,43 @@
         -crop WxH+X+Y   Crop to a rectangular region of width W and height H,
                         starting at point X,Y.
 
+If W or H is larger than the width/height of the input image, then the output
+image is expanded in size, and the expanded region is filled in with zeros
+(neutral gray).  Attaching an 'f' character ("flatten") to the width number
+will cause each block in the expanded region to be filled in with the DC
+coefficient of the nearest block in the input image rather than grayed out.
+Attaching an 'r' character ("reflect") to the width number will cause the
+expanded region to be filled in with repeated reflections of the input image
+rather than grayed out.
+
+A complementary lossless wipe option is provided to discard (gray out) data
+inside a given image region while losslessly preserving what is outside:
+        -wipe WxH+X+Y   Wipe (gray out) a rectangular region of width W and
+                        height H from the input image, starting at point X,Y.
+
+Attaching an 'f' character ("flatten") to the width number will cause the
+region to be filled with the average of adjacent blocks rather than grayed out.
+If the wipe region and the region outside the wipe region, when adjusted to the
+nearest iMCU boundary, form two horizontally adjacent rectangles, then
+attaching an 'r' character ("reflect") to the width number will cause the wipe
+region to be filled with repeated reflections of the outside region rather than
+grayed out.
+
+A lossless drop option is also provided, which allows another JPEG image to be
+inserted ("dropped") into the input image data at a given position, replacing
+the existing image data at that position:
+        -drop +X+Y filename     Drop (insert) another image at point X,Y
+
+Both the input image and the drop image must have the same subsampling level.
+It is best if they also have the same quantization (quality.)  Otherwise, the
+quantization of the output image will be adapted to accommodate the higher of
+the input image quality and the drop image quality.  The trim option can be
+used with the drop option to requantize the drop image to match the input
+image.  Note that a grayscale image can be dropped into a full-color image or
+vice versa, as long as the full-color image has no vertical subsampling.  If
+the input image is grayscale and the drop image is full-color, then the
+chrominance channels from the drop image will be discarded.
+
 Other not-strictly-lossless transformation switches are:
 
         -grayscale      Force grayscale output.
diff --git a/src/third_party/libjpeg-turbo/win/jconfig.h.in b/src/third_party/libjpeg-turbo/win/jconfig.h.in
deleted file mode 100644
index 6db0b34..0000000
--- a/src/third_party/libjpeg-turbo/win/jconfig.h.in
+++ /dev/null
@@ -1,34 +0,0 @@
-#define JPEG_LIB_VERSION  @JPEG_LIB_VERSION@
-#define LIBJPEG_TURBO_VERSION  @VERSION@
-#define LIBJPEG_TURBO_VERSION_NUMBER  @LIBJPEG_TURBO_VERSION_NUMBER@
-
-#cmakedefine C_ARITH_CODING_SUPPORTED
-#cmakedefine D_ARITH_CODING_SUPPORTED
-#cmakedefine MEM_SRCDST_SUPPORTED
-#cmakedefine WITH_SIMD
-
-#define BITS_IN_JSAMPLE  @BITS_IN_JSAMPLE@      /* use 8 or 12 */
-
-#define HAVE_STDDEF_H
-#define HAVE_STDLIB_H
-#undef NEED_SYS_TYPES_H
-#undef NEED_BSD_STRINGS
-
-#define HAVE_UNSIGNED_CHAR
-#define HAVE_UNSIGNED_SHORT
-#undef INCOMPLETE_TYPES_BROKEN
-#undef RIGHT_SHIFT_IS_UNSIGNED
-#undef __CHAR_UNSIGNED__
-
-/* Define "boolean" as unsigned char, not int, per Windows custom */
-#ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
-typedef unsigned char boolean;
-#endif
-#define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
-
-/* Define "INT32" as int, not long, per Windows custom */
-#if !(defined(_BASETSD_H_) || defined(_BASETSD_H))   /* don't conflict if basetsd.h already read */
-typedef short INT16;
-typedef signed int INT32;
-#endif
-#define XMD_H                   /* prevent jmorecfg.h from redefining it */
diff --git a/src/third_party/libjpeg-turbo/win/jpeg62-memsrcdst.def b/src/third_party/libjpeg-turbo/win/jpeg62-memsrcdst.def
deleted file mode 100755
index 4d24a14..0000000
--- a/src/third_party/libjpeg-turbo/win/jpeg62-memsrcdst.def
+++ /dev/null
@@ -1,108 +0,0 @@
-EXPORTS
-  jcopy_block_row @ 1 ;
-  jcopy_sample_rows @ 2 ;
-  jdiv_round_up @ 3 ;
-  jinit_1pass_quantizer @ 4 ;
-  jinit_2pass_quantizer @ 5 ;
-  jinit_c_coef_controller @ 6 ;
-  jinit_c_main_controller @ 7 ;
-  jinit_c_master_control @ 8 ;
-  jinit_c_prep_controller @ 9 ;
-  jinit_color_converter @ 10 ;
-  jinit_color_deconverter @ 11 ;
-  jinit_compress_master @ 12 ;
-  jinit_d_coef_controller @ 13 ;
-  jinit_d_main_controller @ 14 ;
-  jinit_d_post_controller @ 15 ;
-  jinit_downsampler @ 16 ;
-  jinit_forward_dct @ 17 ;
-  jinit_huff_decoder @ 18 ;
-  jinit_huff_encoder @ 19 ;
-  jinit_input_controller @ 20 ;
-  jinit_inverse_dct @ 21 ;
-  jinit_marker_reader @ 22 ;
-  jinit_marker_writer @ 23 ;
-  jinit_master_decompress @ 24 ;
-  jinit_memory_mgr @ 25 ;
-  jinit_merged_upsampler @ 26 ;
-  jinit_phuff_decoder @ 27 ;
-  jinit_phuff_encoder @ 28 ;
-  jinit_upsampler @ 29 ;
-  jpeg_CreateCompress @ 30 ;
-  jpeg_CreateDecompress @ 31 ;
-  jpeg_abort @ 32 ;
-  jpeg_abort_compress @ 33 ;
-  jpeg_abort_decompress @ 34 ;
-  jpeg_add_quant_table @ 35 ;
-  jpeg_alloc_huff_table @ 36 ;
-  jpeg_alloc_quant_table @ 37 ;
-  jpeg_calc_output_dimensions @ 38 ;
-  jpeg_consume_input @ 39 ;
-  jpeg_copy_critical_parameters @ 40 ;
-  jpeg_default_colorspace @ 41 ;
-  jpeg_destroy @ 42 ;
-  jpeg_destroy_compress @ 43 ;
-  jpeg_destroy_decompress @ 44 ;
-  jpeg_fdct_float @ 45 ;
-  jpeg_fdct_ifast @ 46 ;
-  jpeg_fdct_islow @ 47 ;
-  jpeg_fill_bit_buffer @ 48 ;
-  jpeg_finish_compress @ 49 ;
-  jpeg_finish_decompress @ 50 ;
-  jpeg_finish_output @ 51 ;
-  jpeg_free_large @ 52 ;
-  jpeg_free_small @ 53 ;
-  jpeg_gen_optimal_table @ 54 ;
-  jpeg_get_large @ 55 ;
-  jpeg_get_small @ 56 ;
-  jpeg_has_multiple_scans @ 57 ;
-  jpeg_huff_decode @ 58 ;
-  jpeg_idct_1x1 @ 59 ;
-  jpeg_idct_2x2 @ 60 ;
-  jpeg_idct_4x4 @ 61 ;
-  jpeg_idct_float @ 62 ;
-  jpeg_idct_ifast @ 63 ;
-  jpeg_idct_islow @ 64 ;
-  jpeg_input_complete @ 65 ;
-  jpeg_make_c_derived_tbl @ 66 ;
-  jpeg_make_d_derived_tbl @ 67 ;
-  jpeg_mem_available @ 68 ;
-  jpeg_mem_init @ 69 ;
-  jpeg_mem_term @ 70 ;
-  jpeg_new_colormap @ 71 ;
-  jpeg_open_backing_store @ 72 ;
-  jpeg_quality_scaling @ 73 ;
-  jpeg_read_coefficients @ 74 ;
-  jpeg_read_header @ 75 ;
-  jpeg_read_raw_data @ 76 ;
-  jpeg_read_scanlines @ 77 ;
-  jpeg_resync_to_restart @ 78 ;
-  jpeg_save_markers @ 79 ;
-  jpeg_set_colorspace @ 80 ;
-  jpeg_set_defaults @ 81 ;
-  jpeg_set_linear_quality @ 82 ;
-  jpeg_set_marker_processor @ 83 ;
-  jpeg_set_quality @ 84 ;
-  jpeg_simple_progression @ 85 ;
-  jpeg_start_compress @ 86 ;
-  jpeg_start_decompress @ 87 ;
-  jpeg_start_output @ 88 ;
-  jpeg_std_error @ 89 ;
-  jpeg_stdio_dest @ 90 ;
-  jpeg_stdio_src @ 91 ;
-  jpeg_suppress_tables @ 92 ;
-  jpeg_write_coefficients @ 93 ;
-  jpeg_write_m_byte @ 94 ;
-  jpeg_write_m_header @ 95 ;
-  jpeg_write_marker @ 96 ;
-  jpeg_write_raw_data @ 97 ;
-  jpeg_write_scanlines @ 98 ;
-  jpeg_write_tables @ 99 ;
-  jround_up @ 100 ;
-  jzero_far @ 101 ;
-  jpeg_mem_dest @ 102 ;
-  jpeg_mem_src @ 103 ;
-  jpeg_skip_scanlines @ 104 ;
-  jpeg_crop_scanline @ 105 ;
-  jpeg_read_icc_profile @ 106 ;
-  jpeg_write_icc_profile @ 107 ;
diff --git a/src/third_party/libjpeg-turbo/win/jpeg62.def b/src/third_party/libjpeg-turbo/win/jpeg62.def
deleted file mode 100755
index f3c69b2..0000000
--- a/src/third_party/libjpeg-turbo/win/jpeg62.def
+++ /dev/null
@@ -1,106 +0,0 @@
-EXPORTS
-  jcopy_block_row @ 1 ;
-  jcopy_sample_rows @ 2 ;
-  jdiv_round_up @ 3 ;
-  jinit_1pass_quantizer @ 4 ;
-  jinit_2pass_quantizer @ 5 ;
-  jinit_c_coef_controller @ 6 ;
-  jinit_c_main_controller @ 7 ;
-  jinit_c_master_control @ 8 ;
-  jinit_c_prep_controller @ 9 ;
-  jinit_color_converter @ 10 ;
-  jinit_color_deconverter @ 11 ;
-  jinit_compress_master @ 12 ;
-  jinit_d_coef_controller @ 13 ;
-  jinit_d_main_controller @ 14 ;
-  jinit_d_post_controller @ 15 ;
-  jinit_downsampler @ 16 ;
-  jinit_forward_dct @ 17 ;
-  jinit_huff_decoder @ 18 ;
-  jinit_huff_encoder @ 19 ;
-  jinit_input_controller @ 20 ;
-  jinit_inverse_dct @ 21 ;
-  jinit_marker_reader @ 22 ;
-  jinit_marker_writer @ 23 ;
-  jinit_master_decompress @ 24 ;
-  jinit_memory_mgr @ 25 ;
-  jinit_merged_upsampler @ 26 ;
-  jinit_phuff_decoder @ 27 ;
-  jinit_phuff_encoder @ 28 ;
-  jinit_upsampler @ 29 ;
-  jpeg_CreateCompress @ 30 ;
-  jpeg_CreateDecompress @ 31 ;
-  jpeg_abort @ 32 ;
-  jpeg_abort_compress @ 33 ;
-  jpeg_abort_decompress @ 34 ;
-  jpeg_add_quant_table @ 35 ;
-  jpeg_alloc_huff_table @ 36 ;
-  jpeg_alloc_quant_table @ 37 ;
-  jpeg_calc_output_dimensions @ 38 ;
-  jpeg_consume_input @ 39 ;
-  jpeg_copy_critical_parameters @ 40 ;
-  jpeg_default_colorspace @ 41 ;
-  jpeg_destroy @ 42 ;
-  jpeg_destroy_compress @ 43 ;
-  jpeg_destroy_decompress @ 44 ;
-  jpeg_fdct_float @ 45 ;
-  jpeg_fdct_ifast @ 46 ;
-  jpeg_fdct_islow @ 47 ;
-  jpeg_fill_bit_buffer @ 48 ;
-  jpeg_finish_compress @ 49 ;
-  jpeg_finish_decompress @ 50 ;
-  jpeg_finish_output @ 51 ;
-  jpeg_free_large @ 52 ;
-  jpeg_free_small @ 53 ;
-  jpeg_gen_optimal_table @ 54 ;
-  jpeg_get_large @ 55 ;
-  jpeg_get_small @ 56 ;
-  jpeg_has_multiple_scans @ 57 ;
-  jpeg_huff_decode @ 58 ;
-  jpeg_idct_1x1 @ 59 ;
-  jpeg_idct_2x2 @ 60 ;
-  jpeg_idct_4x4 @ 61 ;
-  jpeg_idct_float @ 62 ;
-  jpeg_idct_ifast @ 63 ;
-  jpeg_idct_islow @ 64 ;
-  jpeg_input_complete @ 65 ;
-  jpeg_make_c_derived_tbl @ 66 ;
-  jpeg_make_d_derived_tbl @ 67 ;
-  jpeg_mem_available @ 68 ;
-  jpeg_mem_init @ 69 ;
-  jpeg_mem_term @ 70 ;
-  jpeg_new_colormap @ 71 ;
-  jpeg_open_backing_store @ 72 ;
-  jpeg_quality_scaling @ 73 ;
-  jpeg_read_coefficients @ 74 ;
-  jpeg_read_header @ 75 ;
-  jpeg_read_raw_data @ 76 ;
-  jpeg_read_scanlines @ 77 ;
-  jpeg_resync_to_restart @ 78 ;
-  jpeg_save_markers @ 79 ;
-  jpeg_set_colorspace @ 80 ;
-  jpeg_set_defaults @ 81 ;
-  jpeg_set_linear_quality @ 82 ;
-  jpeg_set_marker_processor @ 83 ;
-  jpeg_set_quality @ 84 ;
-  jpeg_simple_progression @ 85 ;
-  jpeg_start_compress @ 86 ;
-  jpeg_start_decompress @ 87 ;
-  jpeg_start_output @ 88 ;
-  jpeg_std_error @ 89 ;
-  jpeg_stdio_dest @ 90 ;
-  jpeg_stdio_src @ 91 ;
-  jpeg_suppress_tables @ 92 ;
-  jpeg_write_coefficients @ 93 ;
-  jpeg_write_m_byte @ 94 ;
-  jpeg_write_m_header @ 95 ;
-  jpeg_write_marker @ 96 ;
-  jpeg_write_raw_data @ 97 ;
-  jpeg_write_scanlines @ 98 ;
-  jpeg_write_tables @ 99 ;
-  jround_up @ 100 ;
-  jzero_far @ 101 ;
-  jpeg_skip_scanlines @ 102 ;
-  jpeg_crop_scanline @ 103 ;
-  jpeg_read_icc_profile @ 104 ;
-  jpeg_write_icc_profile @ 105 ;
diff --git a/src/third_party/libjpeg-turbo/win/jpeg7-memsrcdst.def b/src/third_party/libjpeg-turbo/win/jpeg7-memsrcdst.def
deleted file mode 100644
index a005aff..0000000
--- a/src/third_party/libjpeg-turbo/win/jpeg7-memsrcdst.def
+++ /dev/null
@@ -1,110 +0,0 @@
-EXPORTS
-  jcopy_block_row @ 1 ;
-  jcopy_sample_rows @ 2 ;
-  jdiv_round_up @ 3 ;
-  jinit_1pass_quantizer @ 4 ;
-  jinit_2pass_quantizer @ 5 ;
-  jinit_c_coef_controller @ 6 ;
-  jinit_c_main_controller @ 7 ;
-  jinit_c_master_control @ 8 ;
-  jinit_c_prep_controller @ 9 ;
-  jinit_color_converter @ 10 ;
-  jinit_color_deconverter @ 11 ;
-  jinit_compress_master @ 12 ;
-  jinit_d_coef_controller @ 13 ;
-  jinit_d_main_controller @ 14 ;
-  jinit_d_post_controller @ 15 ;
-  jinit_downsampler @ 16 ;
-  jinit_forward_dct @ 17 ;
-  jinit_huff_decoder @ 18 ;
-  jinit_huff_encoder @ 19 ;
-  jinit_input_controller @ 20 ;
-  jinit_inverse_dct @ 21 ;
-  jinit_marker_reader @ 22 ;
-  jinit_marker_writer @ 23 ;
-  jinit_master_decompress @ 24 ;
-  jinit_memory_mgr @ 25 ;
-  jinit_merged_upsampler @ 26 ;
-  jinit_phuff_decoder @ 27 ;
-  jinit_phuff_encoder @ 28 ;
-  jinit_upsampler @ 29 ;
-  jpeg_CreateCompress @ 30 ;
-  jpeg_CreateDecompress @ 31 ;
-  jpeg_abort @ 32 ;
-  jpeg_abort_compress @ 33 ;
-  jpeg_abort_decompress @ 34 ;
-  jpeg_add_quant_table @ 35 ;
-  jpeg_alloc_huff_table @ 36 ;
-  jpeg_alloc_quant_table @ 37 ;
-  jpeg_calc_jpeg_dimensions @ 38 ;
-  jpeg_calc_output_dimensions @ 39 ;
-  jpeg_consume_input @ 40 ;
-  jpeg_copy_critical_parameters @ 41 ;
-  jpeg_default_colorspace @ 42 ;
-  jpeg_default_qtables @ 43 ;
-  jpeg_destroy @ 44 ;
-  jpeg_destroy_compress @ 45 ;
-  jpeg_destroy_decompress @ 46 ;
-  jpeg_fdct_float @ 47 ;
-  jpeg_fdct_ifast @ 48 ;
-  jpeg_fdct_islow @ 49 ;
-  jpeg_fill_bit_buffer @ 50 ;
-  jpeg_finish_compress @ 51 ;
-  jpeg_finish_decompress @ 52 ;
-  jpeg_finish_output @ 53 ;
-  jpeg_free_large @ 54 ;
-  jpeg_free_small @ 55 ;
-  jpeg_gen_optimal_table @ 56 ;
-  jpeg_get_large @ 57 ;
-  jpeg_get_small @ 58 ;
-  jpeg_has_multiple_scans @ 59 ;
-  jpeg_huff_decode @ 60 ;
-  jpeg_idct_1x1 @ 61 ;
-  jpeg_idct_2x2 @ 62 ;
-  jpeg_idct_4x4 @ 63 ;
-  jpeg_idct_float @ 64 ;
-  jpeg_idct_ifast @ 65 ;
-  jpeg_idct_islow @ 66 ;
-  jpeg_input_complete @ 67 ;
-  jpeg_make_c_derived_tbl @ 68 ;
-  jpeg_make_d_derived_tbl @ 69 ;
-  jpeg_mem_available @ 70 ;
-  jpeg_mem_init @ 71 ;
-  jpeg_mem_term @ 72 ;
-  jpeg_new_colormap @ 73 ;
-  jpeg_open_backing_store @ 74 ;
-  jpeg_quality_scaling @ 75 ;
-  jpeg_read_coefficients @ 76 ;
-  jpeg_read_header @ 77 ;
-  jpeg_read_raw_data @ 78 ;
-  jpeg_read_scanlines @ 79 ;
-  jpeg_resync_to_restart @ 80 ;
-  jpeg_save_markers @ 81 ;
-  jpeg_set_colorspace @ 82 ;
-  jpeg_set_defaults @ 83 ;
-  jpeg_set_linear_quality @ 84 ;
-  jpeg_set_marker_processor @ 85 ;
-  jpeg_set_quality @ 86 ;
-  jpeg_simple_progression @ 87 ;
-  jpeg_start_compress @ 88 ;
-  jpeg_start_decompress @ 89 ;
-  jpeg_start_output @ 90 ;
-  jpeg_std_error @ 91 ;
-  jpeg_stdio_dest @ 92 ;
-  jpeg_stdio_src @ 93 ;
-  jpeg_suppress_tables @ 94 ;
-  jpeg_write_coefficients @ 95 ;
-  jpeg_write_m_byte @ 96 ;
-  jpeg_write_m_header @ 97 ;
-  jpeg_write_marker @ 98 ;
-  jpeg_write_raw_data @ 99 ;
-  jpeg_write_scanlines @ 100 ;
-  jpeg_write_tables @ 101 ;
-  jround_up @ 102 ;
-  jzero_far @ 103 ;
-  jpeg_mem_dest @ 104 ;
-  jpeg_mem_src @ 105 ;
-  jpeg_skip_scanlines @ 106 ;
-  jpeg_crop_scanline @ 107 ;
-  jpeg_read_icc_profile @ 108 ;
-  jpeg_write_icc_profile @ 109 ;
diff --git a/src/third_party/libjpeg-turbo/win/jpeg7.def b/src/third_party/libjpeg-turbo/win/jpeg7.def
deleted file mode 100644
index 49f4c02..0000000
--- a/src/third_party/libjpeg-turbo/win/jpeg7.def
+++ /dev/null
@@ -1,108 +0,0 @@
-EXPORTS
-  jcopy_block_row @ 1 ;
-  jcopy_sample_rows @ 2 ;
-  jdiv_round_up @ 3 ;
-  jinit_1pass_quantizer @ 4 ;
-  jinit_2pass_quantizer @ 5 ;
-  jinit_c_coef_controller @ 6 ;
-  jinit_c_main_controller @ 7 ;
-  jinit_c_master_control @ 8 ;
-  jinit_c_prep_controller @ 9 ;
-  jinit_color_converter @ 10 ;
-  jinit_color_deconverter @ 11 ;
-  jinit_compress_master @ 12 ;
-  jinit_d_coef_controller @ 13 ;
-  jinit_d_main_controller @ 14 ;
-  jinit_d_post_controller @ 15 ;
-  jinit_downsampler @ 16 ;
-  jinit_forward_dct @ 17 ;
-  jinit_huff_decoder @ 18 ;
-  jinit_huff_encoder @ 19 ;
-  jinit_input_controller @ 20 ;
-  jinit_inverse_dct @ 21 ;
-  jinit_marker_reader @ 22 ;
-  jinit_marker_writer @ 23 ;
-  jinit_master_decompress @ 24 ;
-  jinit_memory_mgr @ 25 ;
-  jinit_merged_upsampler @ 26 ;
-  jinit_phuff_decoder @ 27 ;
-  jinit_phuff_encoder @ 28 ;
-  jinit_upsampler @ 29 ;
-  jpeg_CreateCompress @ 30 ;
-  jpeg_CreateDecompress @ 31 ;
-  jpeg_abort @ 32 ;
-  jpeg_abort_compress @ 33 ;
-  jpeg_abort_decompress @ 34 ;
-  jpeg_add_quant_table @ 35 ;
-  jpeg_alloc_huff_table @ 36 ;
-  jpeg_alloc_quant_table @ 37 ;
-  jpeg_calc_jpeg_dimensions @ 38 ;
-  jpeg_calc_output_dimensions @ 39 ;
-  jpeg_consume_input @ 40 ;
-  jpeg_copy_critical_parameters @ 41 ;
-  jpeg_default_colorspace @ 42 ;
-  jpeg_default_qtables @ 43 ;
-  jpeg_destroy @ 44 ;
-  jpeg_destroy_compress @ 45 ;
-  jpeg_destroy_decompress @ 46 ;
-  jpeg_fdct_float @ 47 ;
-  jpeg_fdct_ifast @ 48 ;
-  jpeg_fdct_islow @ 49 ;
-  jpeg_fill_bit_buffer @ 50 ;
-  jpeg_finish_compress @ 51 ;
-  jpeg_finish_decompress @ 52 ;
-  jpeg_finish_output @ 53 ;
-  jpeg_free_large @ 54 ;
-  jpeg_free_small @ 55 ;
-  jpeg_gen_optimal_table @ 56 ;
-  jpeg_get_large @ 57 ;
-  jpeg_get_small @ 58 ;
-  jpeg_has_multiple_scans @ 59 ;
-  jpeg_huff_decode @ 60 ;
-  jpeg_idct_1x1 @ 61 ;
-  jpeg_idct_2x2 @ 62 ;
-  jpeg_idct_4x4 @ 63 ;
-  jpeg_idct_float @ 64 ;
-  jpeg_idct_ifast @ 65 ;
-  jpeg_idct_islow @ 66 ;
-  jpeg_input_complete @ 67 ;
-  jpeg_make_c_derived_tbl @ 68 ;
-  jpeg_make_d_derived_tbl @ 69 ;
-  jpeg_mem_available @ 70 ;
-  jpeg_mem_init @ 71 ;
-  jpeg_mem_term @ 72 ;
-  jpeg_new_colormap @ 73 ;
-  jpeg_open_backing_store @ 74 ;
-  jpeg_quality_scaling @ 75 ;
-  jpeg_read_coefficients @ 76 ;
-  jpeg_read_header @ 77 ;
-  jpeg_read_raw_data @ 78 ;
-  jpeg_read_scanlines @ 79 ;
-  jpeg_resync_to_restart @ 80 ;
-  jpeg_save_markers @ 81 ;
-  jpeg_set_colorspace @ 82 ;
-  jpeg_set_defaults @ 83 ;
-  jpeg_set_linear_quality @ 84 ;
-  jpeg_set_marker_processor @ 85 ;
-  jpeg_set_quality @ 86 ;
-  jpeg_simple_progression @ 87 ;
-  jpeg_start_compress @ 88 ;
-  jpeg_start_decompress @ 89 ;
-  jpeg_start_output @ 90 ;
-  jpeg_std_error @ 91 ;
-  jpeg_stdio_dest @ 92 ;
-  jpeg_stdio_src @ 93 ;
-  jpeg_suppress_tables @ 94 ;
-  jpeg_write_coefficients @ 95 ;
-  jpeg_write_m_byte @ 96 ;
-  jpeg_write_m_header @ 97 ;
-  jpeg_write_marker @ 98 ;
-  jpeg_write_raw_data @ 99 ;
-  jpeg_write_scanlines @ 100 ;
-  jpeg_write_tables @ 101 ;
-  jround_up @ 102 ;
-  jzero_far @ 103 ;
-  jpeg_skip_scanlines @ 104 ;
-  jpeg_crop_scanline @ 105 ;
-  jpeg_read_icc_profile @ 106 ;
-  jpeg_write_icc_profile @ 107 ;
diff --git a/src/third_party/libjpeg-turbo/win/jpeg8.def b/src/third_party/libjpeg-turbo/win/jpeg8.def
deleted file mode 100644
index 0a53125..0000000
--- a/src/third_party/libjpeg-turbo/win/jpeg8.def
+++ /dev/null
@@ -1,111 +0,0 @@
-EXPORTS
-  jcopy_block_row @ 1 ;
-  jcopy_sample_rows @ 2 ;
-  jdiv_round_up @ 3 ;
-  jinit_1pass_quantizer @ 4 ;
-  jinit_2pass_quantizer @ 5 ;
-  jinit_c_coef_controller @ 6 ;
-  jinit_c_main_controller @ 7 ;
-  jinit_c_master_control @ 8 ;
-  jinit_c_prep_controller @ 9 ;
-  jinit_color_converter @ 10 ;
-  jinit_color_deconverter @ 11 ;
-  jinit_compress_master @ 12 ;
-  jinit_d_coef_controller @ 13 ;
-  jinit_d_main_controller @ 14 ;
-  jinit_d_post_controller @ 15 ;
-  jinit_downsampler @ 16 ;
-  jinit_forward_dct @ 17 ;
-  jinit_huff_decoder @ 18 ;
-  jinit_huff_encoder @ 19 ;
-  jinit_input_controller @ 20 ;
-  jinit_inverse_dct @ 21 ;
-  jinit_marker_reader @ 22 ;
-  jinit_marker_writer @ 23 ;
-  jinit_master_decompress @ 24 ;
-  jinit_memory_mgr @ 25 ;
-  jinit_merged_upsampler @ 26 ;
-  jinit_phuff_decoder @ 27 ;
-  jinit_phuff_encoder @ 28 ;
-  jinit_upsampler @ 29 ;
-  jpeg_CreateCompress @ 30 ;
-  jpeg_CreateDecompress @ 31 ;
-  jpeg_abort @ 32 ;
-  jpeg_abort_compress @ 33 ;
-  jpeg_abort_decompress @ 34 ;
-  jpeg_add_quant_table @ 35 ;
-  jpeg_alloc_huff_table @ 36 ;
-  jpeg_alloc_quant_table @ 37 ;
-  jpeg_calc_jpeg_dimensions @ 38 ;
-  jpeg_calc_output_dimensions @ 39 ;
-  jpeg_consume_input @ 40 ;
-  jpeg_copy_critical_parameters @ 41 ;
-  jpeg_core_output_dimensions @ 42 ;
-  jpeg_default_colorspace @ 43 ;
-  jpeg_default_qtables @ 44 ;
-  jpeg_destroy @ 45 ;
-  jpeg_destroy_compress @ 46 ;
-  jpeg_destroy_decompress @ 47 ;
-  jpeg_fdct_float @ 48 ;
-  jpeg_fdct_ifast @ 49 ;
-  jpeg_fdct_islow @ 50 ;
-  jpeg_fill_bit_buffer @ 51 ;
-  jpeg_finish_compress @ 52 ;
-  jpeg_finish_decompress @ 53 ;
-  jpeg_finish_output @ 54 ;
-  jpeg_free_large @ 55 ;
-  jpeg_free_small @ 56 ;
-  jpeg_gen_optimal_table @ 57 ;
-  jpeg_get_large @ 58 ;
-  jpeg_get_small @ 59 ;
-  jpeg_has_multiple_scans @ 60 ;
-  jpeg_huff_decode @ 61 ;
-  jpeg_idct_1x1 @ 62 ;
-  jpeg_idct_2x2 @ 63 ;
-  jpeg_idct_4x4 @ 64 ;
-  jpeg_idct_float @ 65 ;
-  jpeg_idct_ifast @ 66 ;
-  jpeg_idct_islow @ 67 ;
-  jpeg_input_complete @ 68 ;
-  jpeg_make_c_derived_tbl @ 69 ;
-  jpeg_make_d_derived_tbl @ 70 ;
-  jpeg_mem_available @ 71 ;
-  jpeg_mem_dest @ 72 ;
-  jpeg_mem_init @ 73 ;
-  jpeg_mem_src @ 74 ;
-  jpeg_mem_term @ 75 ;
-  jpeg_new_colormap @ 76 ;
-  jpeg_open_backing_store @ 77 ;
-  jpeg_quality_scaling @ 78 ;
-  jpeg_read_coefficients @ 79 ;
-  jpeg_read_header @ 80 ;
-  jpeg_read_raw_data @ 81 ;
-  jpeg_read_scanlines @ 82 ;
-  jpeg_resync_to_restart @ 83 ;
-  jpeg_save_markers @ 84 ;
-  jpeg_set_colorspace @ 85 ;
-  jpeg_set_defaults @ 86 ;
-  jpeg_set_linear_quality @ 87 ;
-  jpeg_set_marker_processor @ 88 ;
-  jpeg_set_quality @ 89 ;
-  jpeg_simple_progression @ 90 ;
-  jpeg_start_compress @ 91 ;
-  jpeg_start_decompress @ 92 ;
-  jpeg_start_output @ 93 ;
-  jpeg_std_error @ 94 ;
-  jpeg_stdio_dest @ 95 ;
-  jpeg_stdio_src @ 96 ;
-  jpeg_suppress_tables @ 97 ;
-  jpeg_write_coefficients @ 98 ;
-  jpeg_write_m_byte @ 99 ;
-  jpeg_write_m_header @ 100 ;
-  jpeg_write_marker @ 101 ;
-  jpeg_write_raw_data @ 102 ;
-  jpeg_write_scanlines @ 103 ;
-  jpeg_write_tables @ 104 ;
-  jround_up @ 105 ;
-  jzero_far @ 106 ;
-  jpeg_skip_scanlines @ 107 ;
-  jpeg_crop_scanline @ 108 ;
-  jpeg_read_icc_profile @ 109 ;
-  jpeg_write_icc_profile @ 110 ;
diff --git a/src/third_party/libjpeg-turbo/wizard.txt b/src/third_party/libjpeg-turbo/wizard.txt
index ede721e..c57fe38 100644
--- a/src/third_party/libjpeg-turbo/wizard.txt
+++ b/src/third_party/libjpeg-turbo/wizard.txt
@@ -43,7 +43,8 @@
 with '#' and extends to the end of the line.  Here is an example file that
 duplicates the default quantization tables:
 
-        # Quantization tables given in JPEG spec, section K.1
+        # Quantization tables given in Annex K (Clause K.1) of
+        # Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
 
         # This is table 0 (the luminance table):
           16  11  10  16  24  40  51  61
diff --git a/src/third_party/libjpeg-turbo/wrbmp.c b/src/third_party/libjpeg-turbo/wrbmp.c
index 38a64e8..408a722 100644
--- a/src/third_party/libjpeg-turbo/wrbmp.c
+++ b/src/third_party/libjpeg-turbo/wrbmp.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2013, Linaro Limited.
- * Copyright (C) 2014-2015, 2017, D. R. Commander.
+ * Copyright (C) 2014-2015, 2017, 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -141,7 +141,6 @@
     }
   } else if (cinfo->out_color_space == JCS_CMYK) {
     for (col = cinfo->output_width; col > 0; col--) {
-      /* can omit GETJSAMPLE() safely */
       JSAMPLE c = *inptr++, m = *inptr++, y = *inptr++, k = *inptr++;
       cmyk_to_rgb(c, m, y, k, outptr + 2, outptr + 1, outptr);
       outptr += 3;
@@ -153,7 +152,6 @@
     register int ps = rgb_pixelsize[cinfo->out_color_space];
 
     for (col = cinfo->output_width; col > 0; col--) {
-      /* can omit GETJSAMPLE() safely */
       outptr[0] = inptr[bindex];
       outptr[1] = inptr[gindex];
       outptr[2] = inptr[rindex];
@@ -303,9 +301,7 @@
   int bits_per_pixel, cmap_entries;
 
   /* Compute colormap size and total file size */
-  if (cinfo->out_color_space == JCS_RGB ||
-      (cinfo->out_color_space >= JCS_EXT_RGB &&
-       cinfo->out_color_space <= JCS_EXT_ARGB)) {
+  if (IsExtRGB(cinfo->out_color_space)) {
     if (cinfo->quantize_colors) {
       /* Colormapped RGB */
       bits_per_pixel = 8;
@@ -374,18 +370,18 @@
     if (cinfo->out_color_components == 3) {
       /* Normal case with RGB colormap */
       for (i = 0; i < num_colors; i++) {
-        putc(GETJSAMPLE(colormap[2][i]), outfile);
-        putc(GETJSAMPLE(colormap[1][i]), outfile);
-        putc(GETJSAMPLE(colormap[0][i]), outfile);
+        putc(colormap[2][i], outfile);
+        putc(colormap[1][i], outfile);
+        putc(colormap[0][i], outfile);
         if (map_entry_size == 4)
           putc(0, outfile);
       }
     } else {
       /* Grayscale colormap (only happens with grayscale quantization) */
       for (i = 0; i < num_colors; i++) {
-        putc(GETJSAMPLE(colormap[0][i]), outfile);
-        putc(GETJSAMPLE(colormap[0][i]), outfile);
-        putc(GETJSAMPLE(colormap[0][i]), outfile);
+        putc(colormap[0][i], outfile);
+        putc(colormap[0][i], outfile);
+        putc(colormap[0][i], outfile);
         if (map_entry_size == 4)
           putc(0, outfile);
       }
@@ -440,7 +436,6 @@
   JSAMPARRAY image_ptr;
   register JSAMPROW data_ptr;
   JDIMENSION row;
-  register JDIMENSION col;
   cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
 
   if (dest->use_inversion_array) {
@@ -461,10 +456,7 @@
         ((j_common_ptr)cinfo, dest->whole_image, row - 1, (JDIMENSION)1,
          FALSE);
       data_ptr = image_ptr[0];
-      for (col = dest->row_width; col > 0; col--) {
-        putc(GETJSAMPLE(*data_ptr), outfile);
-        data_ptr++;
-      }
+      (void)JFWRITE(outfile, data_ptr, dest->row_width);
     }
     if (progress != NULL)
       progress->completed_extra_passes++;
@@ -499,15 +491,14 @@
 
   if (cinfo->out_color_space == JCS_GRAYSCALE) {
     dest->pub.put_pixel_rows = put_gray_rows;
-  } else if (cinfo->out_color_space == JCS_RGB ||
-             (cinfo->out_color_space >= JCS_EXT_RGB &&
-              cinfo->out_color_space <= JCS_EXT_ARGB)) {
+  } else if (IsExtRGB(cinfo->out_color_space)) {
     if (cinfo->quantize_colors)
       dest->pub.put_pixel_rows = put_gray_rows;
     else
       dest->pub.put_pixel_rows = put_pixel_rows;
-  } else if (cinfo->out_color_space == JCS_RGB565 ||
-             cinfo->out_color_space == JCS_CMYK) {
+  } else if (!cinfo->quantize_colors &&
+             (cinfo->out_color_space == JCS_RGB565 ||
+              cinfo->out_color_space == JCS_CMYK)) {
     dest->pub.put_pixel_rows = put_pixel_rows;
   } else {
     ERREXIT(cinfo, JERR_BMP_COLORSPACE);
diff --git a/src/third_party/libjpeg-turbo/wrgif.c b/src/third_party/libjpeg-turbo/wrgif.c
index 1804e0b..82a2429 100644
--- a/src/third_party/libjpeg-turbo/wrgif.c
+++ b/src/third_party/libjpeg-turbo/wrgif.c
@@ -3,6 +3,7 @@
  *
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2015-2019 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
  * Copyright (C) 2015, 2017, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
@@ -10,12 +11,6 @@
  *
  * This file contains routines to write output images in GIF format.
  *
- **************************************************************************
- * NOTE: to avoid entanglements with Unisys' patent on LZW compression,   *
- * this code has been modified to output "uncompressed GIF" files.        *
- * There is no trace of the LZW algorithm in this file.                   *
- **************************************************************************
- *
  * These routines may need modification for non-Unix environments or
  * specialized applications.  As they stand, they assume output to
  * an ordinary stdio stream.
@@ -33,11 +28,6 @@
  *    copyright notice and this permission notice appear in supporting
  *    documentation.  This software is provided "as is" without express or
  *    implied warranty.
- *
- * We are also required to state that
- *    "The Graphics Interchange Format(c) is the Copyright property of
- *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
- *    CompuServe Incorporated."
  */
 
 #include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
@@ -45,6 +35,37 @@
 #ifdef GIF_SUPPORTED
 
 
+#define MAX_LZW_BITS     12     /* maximum LZW code size (4096 symbols) */
+
+typedef INT16 code_int;         /* must hold -1 .. 2**MAX_LZW_BITS */
+
+#define LZW_TABLE_SIZE   ((code_int)1 << MAX_LZW_BITS)
+
+#define HSIZE            5003   /* hash table size for 80% occupancy */
+
+typedef int hash_int;           /* must hold -2*HSIZE..2*HSIZE */
+
+#define MAXCODE(n_bits)  (((code_int)1 << (n_bits)) - 1)
+
+
+/*
+ * The LZW hash table consists of two parallel arrays:
+ *   hash_code[i]       code of symbol in slot i, or 0 if empty slot
+ *   hash_value[i]      symbol's value; undefined if empty slot
+ * where slot values (i) range from 0 to HSIZE-1.  The symbol value is
+ * its prefix symbol's code concatenated with its suffix character.
+ *
+ * Algorithm:  use open addressing double hashing (no chaining) on the
+ * prefix code / suffix character combination.  We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe.
+ */
+
+typedef int hash_entry;         /* must hold (code_int << 8) | byte */
+
+#define HASH_ENTRY(prefix, suffix)  ((((hash_entry)(prefix)) << 8) | (suffix))
+
+
 /* Private version of data destination object */
 
 typedef struct {
@@ -54,14 +75,24 @@
 
   /* State for packing variable-width codes into a bitstream */
   int n_bits;                   /* current number of bits/code */
-  int maxcode;                  /* maximum code, given n_bits */
-  long cur_accum;               /* holds bits not yet output */
+  code_int maxcode;             /* maximum code, given n_bits */
+  int init_bits;                /* initial n_bits ... restored after clear */
+  int cur_accum;                /* holds bits not yet output */
   int cur_bits;                 /* # of bits in cur_accum */
 
+  /* LZW string construction */
+  code_int waiting_code;        /* symbol not yet output; may be extendable */
+  boolean first_byte;           /* if TRUE, waiting_code is not valid */
+
   /* State for GIF code assignment */
-  int ClearCode;                /* clear code (doesn't change) */
-  int EOFCode;                  /* EOF code (ditto) */
-  int code_counter;             /* counts output symbols */
+  code_int ClearCode;           /* clear code (doesn't change) */
+  code_int EOFCode;             /* EOF code (ditto) */
+  code_int free_code;           /* LZW: first not-yet-used symbol code */
+  code_int code_counter;        /* not LZW: counts output symbols */
+
+  /* LZW hash table */
+  code_int *hash_code;          /* => hash table of symbol codes */
+  hash_entry *hash_value;       /* => hash table of symbol values */
 
   /* GIF data packet construction buffer */
   int bytesinpkt;               /* # of bytes in current packet */
@@ -71,9 +102,6 @@
 
 typedef gif_dest_struct *gif_dest_ptr;
 
-/* Largest value that will fit in N bits */
-#define MAXCODE(n_bits)  ((1 << (n_bits)) - 1)
-
 
 /*
  * Routines to package finished data bytes into GIF data blocks.
@@ -105,7 +133,7 @@
 /* Routine to convert variable-width codes into a byte stream */
 
 LOCAL(void)
-output(gif_dest_ptr dinfo, int code)
+output(gif_dest_ptr dinfo, code_int code)
 /* Emit a code of n_bits bits */
 /* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
 {
@@ -117,74 +145,76 @@
     dinfo->cur_accum >>= 8;
     dinfo->cur_bits -= 8;
   }
+
+  /*
+   * If the next entry is going to be too big for the code size,
+   * then increase it, if possible.  We do this here to ensure
+   * that it's done in sync with the decoder's codesize increases.
+   */
+  if (dinfo->free_code > dinfo->maxcode) {
+    dinfo->n_bits++;
+    if (dinfo->n_bits == MAX_LZW_BITS)
+      dinfo->maxcode = LZW_TABLE_SIZE; /* free_code will never exceed this */
+    else
+      dinfo->maxcode = MAXCODE(dinfo->n_bits);
+  }
 }
 
 
-/* The pseudo-compression algorithm.
- *
- * In this module we simply output each pixel value as a separate symbol;
- * thus, no compression occurs.  In fact, there is expansion of one bit per
- * pixel, because we use a symbol width one bit wider than the pixel width.
- *
- * GIF ordinarily uses variable-width symbols, and the decoder will expect
- * to ratchet up the symbol width after a fixed number of symbols.
- * To simplify the logic and keep the expansion penalty down, we emit a
- * GIF Clear code to reset the decoder just before the width would ratchet up.
- * Thus, all the symbols in the output file will have the same bit width.
- * Note that emitting the Clear codes at the right times is a mere matter of
- * counting output symbols and is in no way dependent on the LZW patent.
- *
- * With a small basic pixel width (low color count), Clear codes will be
- * needed very frequently, causing the file to expand even more.  So this
- * simplistic approach wouldn't work too well on bilevel images, for example.
- * But for output of JPEG conversions the pixel width will usually be 8 bits
- * (129 to 256 colors), so the overhead added by Clear symbols is only about
- * one symbol in every 256.
- */
+/* Compression initialization & termination */
+
+
+LOCAL(void)
+clear_hash(gif_dest_ptr dinfo)
+/* Fill the hash table with empty entries */
+{
+  /* It's sufficient to zero hash_code[] */
+  MEMZERO(dinfo->hash_code, HSIZE * sizeof(code_int));
+}
+
+
+LOCAL(void)
+clear_block(gif_dest_ptr dinfo)
+/* Reset compressor and issue a Clear code */
+{
+  clear_hash(dinfo);                    /* delete all the symbols */
+  dinfo->free_code = dinfo->ClearCode + 2;
+  output(dinfo, dinfo->ClearCode);      /* inform decoder */
+  dinfo->n_bits = dinfo->init_bits;     /* reset code size */
+  dinfo->maxcode = MAXCODE(dinfo->n_bits);
+}
+
 
 LOCAL(void)
 compress_init(gif_dest_ptr dinfo, int i_bits)
-/* Initialize pseudo-compressor */
+/* Initialize compressor */
 {
   /* init all the state variables */
-  dinfo->n_bits = i_bits;
+  dinfo->n_bits = dinfo->init_bits = i_bits;
   dinfo->maxcode = MAXCODE(dinfo->n_bits);
-  dinfo->ClearCode = (1 << (i_bits - 1));
+  dinfo->ClearCode = ((code_int) 1 << (i_bits - 1));
   dinfo->EOFCode = dinfo->ClearCode + 1;
-  dinfo->code_counter = dinfo->ClearCode + 2;
+  dinfo->code_counter = dinfo->free_code = dinfo->ClearCode + 2;
+  dinfo->first_byte = TRUE;     /* no waiting symbol yet */
   /* init output buffering vars */
   dinfo->bytesinpkt = 0;
   dinfo->cur_accum = 0;
   dinfo->cur_bits = 0;
+  /* clear hash table */
+  if (dinfo->hash_code != NULL)
+    clear_hash(dinfo);
   /* GIF specifies an initial Clear code */
   output(dinfo, dinfo->ClearCode);
 }
 
 
 LOCAL(void)
-compress_pixel(gif_dest_ptr dinfo, int c)
-/* Accept and "compress" one pixel value.
- * The given value must be less than n_bits wide.
- */
-{
-  /* Output the given pixel value as a symbol. */
-  output(dinfo, c);
-  /* Issue Clear codes often enough to keep the reader from ratcheting up
-   * its symbol size.
-   */
-  if (dinfo->code_counter < dinfo->maxcode) {
-    dinfo->code_counter++;
-  } else {
-    output(dinfo, dinfo->ClearCode);
-    dinfo->code_counter = dinfo->ClearCode + 2; /* reset the counter */
-  }
-}
-
-
-LOCAL(void)
 compress_term(gif_dest_ptr dinfo)
 /* Clean up at end */
 {
+  /* Flush out the buffered LZW code */
+  if (!dinfo->first_byte)
+    output(dinfo, dinfo->waiting_code);
   /* Send an EOF code */
   output(dinfo, dinfo->EOFCode);
   /* Flush the bit-packing buffer */
@@ -221,7 +251,7 @@
 LOCAL(void)
 emit_header(gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
 /* Output the GIF file header, including color map */
-/* If colormap==NULL, synthesize a grayscale colormap */
+/* If colormap == NULL, synthesize a grayscale colormap */
 {
   int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
   int cshift = dinfo->cinfo->data_precision - 8;
@@ -265,12 +295,12 @@
       if (colormap != NULL) {
         if (dinfo->cinfo->out_color_space == JCS_RGB) {
           /* Normal case: RGB color map */
-          putc(GETJSAMPLE(colormap[0][i]) >> cshift, dinfo->pub.output_file);
-          putc(GETJSAMPLE(colormap[1][i]) >> cshift, dinfo->pub.output_file);
-          putc(GETJSAMPLE(colormap[2][i]) >> cshift, dinfo->pub.output_file);
+          putc(colormap[0][i] >> cshift, dinfo->pub.output_file);
+          putc(colormap[1][i] >> cshift, dinfo->pub.output_file);
+          putc(colormap[2][i] >> cshift, dinfo->pub.output_file);
         } else {
           /* Grayscale "color map": possible if quantizing grayscale image */
-          put_3bytes(dinfo, GETJSAMPLE(colormap[0][i]) >> cshift);
+          put_3bytes(dinfo, colormap[0][i] >> cshift);
         }
       } else {
         /* Create a grayscale map of num_colors values, range 0..255 */
@@ -278,7 +308,7 @@
       }
     } else {
       /* fill out the map to a power of 2 */
-      put_3bytes(dinfo, 0);
+      put_3bytes(dinfo, CENTERJSAMPLE >> cshift);
     }
   }
   /* Write image separator and Image Descriptor */
@@ -292,7 +322,7 @@
   /* Write Initial Code Size byte */
   putc(InitCodeSize, dinfo->pub.output_file);
 
-  /* Initialize for "compression" of image data */
+  /* Initialize for compression of image data */
   compress_init(dinfo, InitCodeSize + 1);
 }
 
@@ -318,17 +348,139 @@
  * In this module rows_supplied will always be 1.
  */
 
+
+/*
+ * The LZW algorithm proper
+ */
+
 METHODDEF(void)
-put_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
-               JDIMENSION rows_supplied)
+put_LZW_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
+                   JDIMENSION rows_supplied)
 {
   gif_dest_ptr dest = (gif_dest_ptr)dinfo;
   register JSAMPROW ptr;
   register JDIMENSION col;
+  code_int c;
+  register hash_int i;
+  register hash_int disp;
+  register hash_entry probe_value;
 
   ptr = dest->pub.buffer[0];
   for (col = cinfo->output_width; col > 0; col--) {
-    compress_pixel(dest, GETJSAMPLE(*ptr++));
+    /* Accept and compress one 8-bit byte */
+    c = (code_int)(*ptr++);
+
+    if (dest->first_byte) {     /* need to initialize waiting_code */
+      dest->waiting_code = c;
+      dest->first_byte = FALSE;
+      continue;
+    }
+
+    /* Probe hash table to see if a symbol exists for
+     * waiting_code followed by c.
+     * If so, replace waiting_code by that symbol and continue.
+     */
+    i = ((hash_int)c << (MAX_LZW_BITS - 8)) + dest->waiting_code;
+    /* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */
+    if (i >= HSIZE)
+      i -= HSIZE;
+
+    probe_value = HASH_ENTRY(dest->waiting_code, c);
+
+    if (dest->hash_code[i] == 0) {
+      /* hit empty slot; desired symbol not in table */
+      output(dest, dest->waiting_code);
+      if (dest->free_code < LZW_TABLE_SIZE) {
+        dest->hash_code[i] = dest->free_code++; /* add symbol to hashtable */
+        dest->hash_value[i] = probe_value;
+      } else
+        clear_block(dest);
+      dest->waiting_code = c;
+      continue;
+    }
+    if (dest->hash_value[i] == probe_value) {
+      dest->waiting_code = dest->hash_code[i];
+      continue;
+    }
+
+    if (i == 0)                 /* secondary hash (after G. Knott) */
+      disp = 1;
+    else
+      disp = HSIZE - i;
+    for (;;) {
+      i -= disp;
+      if (i < 0)
+        i += HSIZE;
+      if (dest->hash_code[i] == 0) {
+        /* hit empty slot; desired symbol not in table */
+        output(dest, dest->waiting_code);
+        if (dest->free_code < LZW_TABLE_SIZE) {
+          dest->hash_code[i] = dest->free_code++; /* add symbol to hashtable */
+          dest->hash_value[i] = probe_value;
+        } else
+          clear_block(dest);
+        dest->waiting_code = c;
+        break;
+      }
+      if (dest->hash_value[i] == probe_value) {
+        dest->waiting_code = dest->hash_code[i];
+        break;
+      }
+    }
+  }
+}
+
+
+/*
+ * The pseudo-compression algorithm.
+ *
+ * In this version we simply output each pixel value as a separate symbol;
+ * thus, no compression occurs.  In fact, there is expansion of one bit per
+ * pixel, because we use a symbol width one bit wider than the pixel width.
+ *
+ * GIF ordinarily uses variable-width symbols, and the decoder will expect
+ * to ratchet up the symbol width after a fixed number of symbols.
+ * To simplify the logic and keep the expansion penalty down, we emit a
+ * GIF Clear code to reset the decoder just before the width would ratchet up.
+ * Thus, all the symbols in the output file will have the same bit width.
+ * Note that emitting the Clear codes at the right times is a mere matter of
+ * counting output symbols and is in no way dependent on the LZW algorithm.
+ *
+ * With a small basic pixel width (low color count), Clear codes will be
+ * needed very frequently, causing the file to expand even more.  So this
+ * simplistic approach wouldn't work too well on bilevel images, for example.
+ * But for output of JPEG conversions the pixel width will usually be 8 bits
+ * (129 to 256 colors), so the overhead added by Clear symbols is only about
+ * one symbol in every 256.
+ */
+
+METHODDEF(void)
+put_raw_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
+                   JDIMENSION rows_supplied)
+{
+  gif_dest_ptr dest = (gif_dest_ptr)dinfo;
+  register JSAMPROW ptr;
+  register JDIMENSION col;
+  code_int c;
+
+  ptr = dest->pub.buffer[0];
+  for (col = cinfo->output_width; col > 0; col--) {
+    c = (code_int)(*ptr++);
+    /* Accept and output one pixel value.
+     * The given value must be less than n_bits wide.
+     */
+
+    /* Output the given pixel value as a symbol. */
+    output(dest, c);
+    /* Issue Clear codes often enough to keep the reader from ratcheting up
+     * its symbol size.
+     */
+    if (dest->code_counter < dest->maxcode) {
+      dest->code_counter++;
+    } else {
+      output(dest, dest->ClearCode);
+      dest->code_counter = dest->ClearCode + 2; /* reset the counter */
+    }
   }
 }
 
@@ -342,7 +494,7 @@
 {
   gif_dest_ptr dest = (gif_dest_ptr)dinfo;
 
-  /* Flush "compression" mechanism */
+  /* Flush compression mechanism */
   compress_term(dest);
   /* Write a zero-length data block to end the series */
   putc(0, dest->pub.output_file);
@@ -370,7 +522,7 @@
  */
 
 GLOBAL(djpeg_dest_ptr)
-jinit_write_gif(j_decompress_ptr cinfo)
+jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw)
 {
   gif_dest_ptr dest;
 
@@ -380,7 +532,6 @@
                                 sizeof(gif_dest_struct));
   dest->cinfo = cinfo;          /* make back link for subroutines */
   dest->pub.start_output = start_output_gif;
-  dest->pub.put_pixel_rows = put_pixel_rows;
   dest->pub.finish_output = finish_output_gif;
   dest->pub.calc_buffer_dimensions = calc_buffer_dimensions_gif;
 
@@ -407,6 +558,22 @@
     ((j_common_ptr)cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION)1);
   dest->pub.buffer_height = 1;
 
+  if (is_lzw) {
+    dest->pub.put_pixel_rows = put_LZW_pixel_rows;
+    /* Allocate space for hash table */
+    dest->hash_code = (code_int *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                  HSIZE * sizeof(code_int));
+    dest->hash_value = (hash_entry *)
+      (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+                                  HSIZE * sizeof(hash_entry));
+  } else {
+    dest->pub.put_pixel_rows = put_raw_pixel_rows;
+    /* Mark tables unused */
+    dest->hash_code = NULL;
+    dest->hash_value = NULL;
+  }
+
   return (djpeg_dest_ptr)dest;
 }
 
diff --git a/src/third_party/libjpeg-turbo/wrjpgcom.c b/src/third_party/libjpeg-turbo/wrjpgcom.c
index faf77b4..8a4e741 100644
--- a/src/third_party/libjpeg-turbo/wrjpgcom.c
+++ b/src/third_party/libjpeg-turbo/wrjpgcom.c
@@ -580,7 +580,7 @@
     }
   }
   /* Duplicate the remainder of the source file.
-   * Note that any COM markers occuring after SOF will not be touched.
+   * Note that any COM markers occurring after SOF will not be touched.
    */
   write_marker(marker);
   copy_rest_of_file();
diff --git a/src/third_party/libjpeg-turbo/wrppm.c b/src/third_party/libjpeg-turbo/wrppm.c
index 819a0a7..3081ec3 100644
--- a/src/third_party/libjpeg-turbo/wrppm.c
+++ b/src/third_party/libjpeg-turbo/wrppm.c
@@ -5,7 +5,7 @@
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * Modified 2009 by Guido Vollbeding.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2017, D. R. Commander.
+ * Copyright (C) 2017, 2019-2020, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -108,17 +108,17 @@
   ppm_dest_ptr dest = (ppm_dest_ptr)dinfo;
   register char *bufferptr;
   register JSAMPROW ptr;
-#if BITS_IN_JSAMPLE != 8 || (!defined(HAVE_UNSIGNED_CHAR) && !defined(__CHAR_UNSIGNED__))
+#if BITS_IN_JSAMPLE != 8
   register JDIMENSION col;
 #endif
 
   ptr = dest->pub.buffer[0];
   bufferptr = dest->iobuffer;
-#if BITS_IN_JSAMPLE == 8 && (defined(HAVE_UNSIGNED_CHAR) || defined(__CHAR_UNSIGNED__))
+#if BITS_IN_JSAMPLE == 8
   MEMCOPY(bufferptr, ptr, dest->samples_per_row);
 #else
   for (col = dest->samples_per_row; col > 0; col--) {
-    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++));
+    PUTPPMSAMPLE(bufferptr, *ptr++);
   }
 #endif
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
@@ -200,10 +200,10 @@
   ptr = dest->pub.buffer[0];
   bufferptr = dest->iobuffer;
   for (col = cinfo->output_width; col > 0; col--) {
-    pixval = GETJSAMPLE(*ptr++);
-    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval]));
-    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval]));
-    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval]));
+    pixval = *ptr++;
+    PUTPPMSAMPLE(bufferptr, color_map0[pixval]);
+    PUTPPMSAMPLE(bufferptr, color_map1[pixval]);
+    PUTPPMSAMPLE(bufferptr, color_map2[pixval]);
   }
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
 }
@@ -222,7 +222,7 @@
   ptr = dest->pub.buffer[0];
   bufferptr = dest->iobuffer;
   for (col = cinfo->output_width; col > 0; col--) {
-    PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)]));
+    PUTPPMSAMPLE(bufferptr, color_map[*ptr++]);
   }
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
 }
@@ -256,6 +256,8 @@
   case JCS_EXT_ABGR:
   case JCS_EXT_ARGB:
   case JCS_CMYK:
+    if (!IsExtRGB(cinfo->out_color_space) && cinfo->quantize_colors)
+      ERREXIT(cinfo, JERR_PPM_COLORSPACE);
     /* emit header for raw PPM format */
     fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n",
             (long)cinfo->output_width, (long)cinfo->output_height, PPM_MAXVAL);
@@ -324,11 +326,12 @@
 
   if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 ||
       sizeof(JSAMPLE) != sizeof(char) ||
-      (cinfo->out_color_space != JCS_EXT_RGB
 #if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
-       && cinfo->out_color_space != JCS_RGB
+      (cinfo->out_color_space != JCS_EXT_RGB &&
+       cinfo->out_color_space != JCS_RGB)) {
+#else
+      cinfo->out_color_space != JCS_EXT_RGB) {
 #endif
-      )) {
     /* When quantizing, we need an output buffer for colormap indexes
      * that's separate from the physical I/O buffer.  We also need a
      * separate buffer if pixel format translation must take place.
@@ -337,13 +340,14 @@
       ((j_common_ptr)cinfo, JPOOL_IMAGE,
        cinfo->output_width * cinfo->output_components, (JDIMENSION)1);
     dest->pub.buffer_height = 1;
-    if (IsExtRGB(cinfo->out_color_space))
-      dest->pub.put_pixel_rows = put_rgb;
-    else if (cinfo->out_color_space == JCS_CMYK)
-      dest->pub.put_pixel_rows = put_cmyk;
-    else if (!cinfo->quantize_colors)
-      dest->pub.put_pixel_rows = copy_pixel_rows;
-    else if (cinfo->out_color_space == JCS_GRAYSCALE)
+    if (!cinfo->quantize_colors) {
+      if (IsExtRGB(cinfo->out_color_space))
+        dest->pub.put_pixel_rows = put_rgb;
+      else if (cinfo->out_color_space == JCS_CMYK)
+        dest->pub.put_pixel_rows = put_cmyk;
+      else
+        dest->pub.put_pixel_rows = copy_pixel_rows;
+    } else if (cinfo->out_color_space == JCS_GRAYSCALE)
       dest->pub.put_pixel_rows = put_demapped_gray;
     else
       dest->pub.put_pixel_rows = put_demapped_rgb;
diff --git a/src/third_party/libjpeg-turbo/wrrle.c b/src/third_party/libjpeg-turbo/wrrle.c
deleted file mode 100644
index 5c98ec0..0000000
--- a/src/third_party/libjpeg-turbo/wrrle.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * wrrle.c
- *
- * This file was part of the Independent JPEG Group's software:
- * Copyright (C) 1991-1996, Thomas G. Lane.
- * libjpeg-turbo Modifications:
- * Copyright (C) 2017, D. R. Commander.
- * For conditions of distribution and use, see the accompanying README.ijg
- * file.
- *
- * This file contains routines to write output images in RLE format.
- * The Utah Raster Toolkit library is required (version 3.1 or later).
- *
- * These routines may need modification for non-Unix environments or
- * specialized applications.  As they stand, they assume output to
- * an ordinary stdio stream.
- *
- * Based on code contributed by Mike Lijewski,
- * with updates from Robert Hutchinson.
- */
-
-#include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
-
-#ifdef RLE_SUPPORTED
-
-/* rle.h is provided by the Utah Raster Toolkit. */
-
-#include <rle.h>
-
-/*
- * We assume that JSAMPLE has the same representation as rle_pixel,
- * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
- */
-
-#if BITS_IN_JSAMPLE != 8
-  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
-#endif
-
-
-/*
- * Since RLE stores scanlines bottom-to-top, we have to invert the image
- * from JPEG's top-to-bottom order.  To do this, we save the outgoing data
- * in a virtual array during put_pixel_row calls, then actually emit the
- * RLE file during finish_output.
- */
-
-
-/*
- * For now, if we emit an RLE color map then it is always 256 entries long,
- * though not all of the entries need be used.
- */
-
-#define CMAPBITS        8
-#define CMAPLENGTH      (1 << (CMAPBITS))
-
-typedef struct {
-  struct djpeg_dest_struct pub; /* public fields */
-
-  jvirt_sarray_ptr image;       /* virtual array to store the output image */
-  rle_map *colormap;            /* RLE-style color map, or NULL if none */
-  rle_pixel **rle_row;          /* To pass rows to rle_putrow() */
-
-} rle_dest_struct;
-
-typedef rle_dest_struct *rle_dest_ptr;
-
-/* Forward declarations */
-METHODDEF(void) rle_put_pixel_rows(j_decompress_ptr cinfo,
-                                   djpeg_dest_ptr dinfo,
-                                   JDIMENSION rows_supplied);
-
-
-/*
- * Write the file header.
- *
- * In this module it's easier to wait till finish_output to write anything.
- */
-
-METHODDEF(void)
-start_output_rle(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
-{
-  rle_dest_ptr dest = (rle_dest_ptr)dinfo;
-  size_t cmapsize;
-  int i, ci;
-#ifdef PROGRESS_REPORT
-  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
-#endif
-
-  /*
-   * Make sure the image can be stored in RLE format.
-   *
-   * - RLE stores image dimensions as *signed* 16 bit integers.  JPEG
-   *   uses unsigned, so we have to check the width.
-   *
-   * - Colorspace is expected to be grayscale or RGB.
-   *
-   * - The number of channels (components) is expected to be 1 (grayscale/
-   *   pseudocolor) or 3 (truecolor/directcolor).
-   *   (could be 2 or 4 if using an alpha channel, but we aren't)
-   */
-
-  if (cinfo->output_width > 32767 || cinfo->output_height > 32767)
-    ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width,
-             cinfo->output_height);
-
-  if (cinfo->out_color_space != JCS_GRAYSCALE &&
-      cinfo->out_color_space != JCS_RGB)
-    ERREXIT(cinfo, JERR_RLE_COLORSPACE);
-
-  if (cinfo->output_components != 1 && cinfo->output_components != 3)
-    ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components);
-
-  /* Convert colormap, if any, to RLE format. */
-
-  dest->colormap = NULL;
-
-  if (cinfo->quantize_colors) {
-    /* Allocate storage for RLE-style cmap, zero any extra entries */
-    cmapsize = cinfo->out_color_components * CMAPLENGTH * sizeof(rle_map);
-    dest->colormap = (rle_map *)(*cinfo->mem->alloc_small)
-      ((j_common_ptr)cinfo, JPOOL_IMAGE, cmapsize);
-    MEMZERO(dest->colormap, cmapsize);
-
-    /* Save away data in RLE format --- note 8-bit left shift! */
-    /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
-    for (ci = 0; ci < cinfo->out_color_components; ci++) {
-      for (i = 0; i < cinfo->actual_number_of_colors; i++) {
-        dest->colormap[ci * CMAPLENGTH + i] =
-          GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
-      }
-    }
-  }
-
-  /* Set the output buffer to the first row */
-  dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
-    ((j_common_ptr)cinfo, dest->image, (JDIMENSION)0, (JDIMENSION)1, TRUE);
-  dest->pub.buffer_height = 1;
-
-  dest->pub.put_pixel_rows = rle_put_pixel_rows;
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL) {
-    progress->total_extra_passes++;  /* count file writing as separate pass */
-  }
-#endif
-}
-
-
-/*
- * Write some pixel data.
- *
- * This routine just saves the data away in a virtual array.
- */
-
-METHODDEF(void)
-rle_put_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
-                   JDIMENSION rows_supplied)
-{
-  rle_dest_ptr dest = (rle_dest_ptr)dinfo;
-
-  if (cinfo->output_scanline < cinfo->output_height) {
-    dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
-      ((j_common_ptr)cinfo, dest->image,
-       cinfo->output_scanline, (JDIMENSION)1, TRUE);
-  }
-}
-
-/*
- * Finish up at the end of the file.
- *
- * Here is where we really output the RLE file.
- */
-
-METHODDEF(void)
-finish_output_rle(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
-{
-  rle_dest_ptr dest = (rle_dest_ptr)dinfo;
-  rle_hdr header;               /* Output file information */
-  rle_pixel **rle_row, *red, *green, *blue;
-  JSAMPROW output_row;
-  char cmapcomment[80];
-  int row, col;
-  int ci;
-#ifdef PROGRESS_REPORT
-  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
-#endif
-
-  /* Initialize the header info */
-  header = *rle_hdr_init(NULL);
-  header.rle_file = dest->pub.output_file;
-  header.xmin     = 0;
-  header.xmax     = cinfo->output_width  - 1;
-  header.ymin     = 0;
-  header.ymax     = cinfo->output_height - 1;
-  header.alpha    = 0;
-  header.ncolors  = cinfo->output_components;
-  for (ci = 0; ci < cinfo->output_components; ci++) {
-    RLE_SET_BIT(header, ci);
-  }
-  if (cinfo->quantize_colors) {
-    header.ncmap   = cinfo->out_color_components;
-    header.cmaplen = CMAPBITS;
-    header.cmap    = dest->colormap;
-    /* Add a comment to the output image with the true colormap length. */
-    sprintf(cmapcomment, "color_map_length=%d",
-            cinfo->actual_number_of_colors);
-    rle_putcom(cmapcomment, &header);
-  }
-
-  /* Emit the RLE header and color map (if any) */
-  rle_put_setup(&header);
-
-  /* Now output the RLE data from our virtual array.
-   * We assume here that rle_pixel is represented the same as JSAMPLE.
-   */
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL) {
-    progress->pub.pass_limit = cinfo->output_height;
-    progress->pub.pass_counter = 0;
-    (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-  }
-#endif
-
-  if (cinfo->output_components == 1) {
-    for (row = cinfo->output_height - 1; row >= 0; row--) {
-      rle_row = (rle_pixel **)(*cinfo->mem->access_virt_sarray)
-        ((j_common_ptr)cinfo, dest->image,
-         (JDIMENSION)row, (JDIMENSION)1, FALSE);
-      rle_putrow(rle_row, (int)cinfo->output_width, &header);
-#ifdef PROGRESS_REPORT
-      if (progress != NULL) {
-        progress->pub.pass_counter++;
-        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-      }
-#endif
-    }
-  } else {
-    for (row = cinfo->output_height - 1; row >= 0; row--) {
-      rle_row = (rle_pixel **)dest->rle_row;
-      output_row = *(*cinfo->mem->access_virt_sarray)
-        ((j_common_ptr)cinfo, dest->image,
-         (JDIMENSION)row, (JDIMENSION)1, FALSE);
-      red = rle_row[0];
-      green = rle_row[1];
-      blue = rle_row[2];
-      for (col = cinfo->output_width; col > 0; col--) {
-        *red++ = GETJSAMPLE(*output_row++);
-        *green++ = GETJSAMPLE(*output_row++);
-        *blue++ = GETJSAMPLE(*output_row++);
-      }
-      rle_putrow(rle_row, (int)cinfo->output_width, &header);
-#ifdef PROGRESS_REPORT
-      if (progress != NULL) {
-        progress->pub.pass_counter++;
-        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
-      }
-#endif
-    }
-  }
-
-#ifdef PROGRESS_REPORT
-  if (progress != NULL)
-    progress->completed_extra_passes++;
-#endif
-
-  /* Emit file trailer */
-  rle_puteof(&header);
-  fflush(dest->pub.output_file);
-  if (ferror(dest->pub.output_file))
-    ERREXIT(cinfo, JERR_FILE_WRITE);
-}
-
-
-/*
- * The module selection routine for RLE format output.
- */
-
-GLOBAL(djpeg_dest_ptr)
-jinit_write_rle(j_decompress_ptr cinfo)
-{
-  rle_dest_ptr dest;
-
-  /* Create module interface object, fill in method pointers */
-  dest = (rle_dest_ptr)
-    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
-                                sizeof(rle_dest_struct));
-  dest->pub.start_output = start_output_rle;
-  dest->pub.finish_output = finish_output_rle;
-  dest->pub.calc_buffer_dimensions = NULL;
-
-  /* Calculate output image dimensions so we can allocate space */
-  jpeg_calc_output_dimensions(cinfo);
-
-  /* Allocate a work array for output to the RLE library. */
-  dest->rle_row = (*cinfo->mem->alloc_sarray)
-    ((j_common_ptr)cinfo, JPOOL_IMAGE,
-     cinfo->output_width, (JDIMENSION)cinfo->output_components);
-
-  /* Allocate a virtual array to hold the image. */
-  dest->image = (*cinfo->mem->request_virt_sarray)
-    ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
-     (JDIMENSION)(cinfo->output_width * cinfo->output_components),
-     cinfo->output_height, (JDIMENSION)1);
-
-  return (djpeg_dest_ptr)dest;
-}
-
-#endif /* RLE_SUPPORTED */
diff --git a/src/third_party/libjpeg-turbo/wrtarga.c b/src/third_party/libjpeg-turbo/wrtarga.c
index 9dfa920..7a654ff 100644
--- a/src/third_party/libjpeg-turbo/wrtarga.c
+++ b/src/third_party/libjpeg-turbo/wrtarga.c
@@ -4,7 +4,7 @@
  * This file was part of the Independent JPEG Group's software:
  * Copyright (C) 1991-1996, Thomas G. Lane.
  * libjpeg-turbo Modifications:
- * Copyright (C) 2017, D. R. Commander.
+ * Copyright (C) 2017, 2019, D. R. Commander.
  * For conditions of distribution and use, see the accompanying README.ijg
  * file.
  *
@@ -102,9 +102,9 @@
   inptr = dest->pub.buffer[0];
   outptr = dest->iobuffer;
   for (col = cinfo->output_width; col > 0; col--) {
-    outptr[0] = (char)GETJSAMPLE(inptr[2]); /* RGB to BGR order */
-    outptr[1] = (char)GETJSAMPLE(inptr[1]);
-    outptr[2] = (char)GETJSAMPLE(inptr[0]);
+    outptr[0] = inptr[2]; /* RGB to BGR order */
+    outptr[1] = inptr[1];
+    outptr[2] = inptr[0];
     inptr += 3, outptr += 3;
   }
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
@@ -118,13 +118,10 @@
   tga_dest_ptr dest = (tga_dest_ptr)dinfo;
   register JSAMPROW inptr;
   register char *outptr;
-  register JDIMENSION col;
 
   inptr = dest->pub.buffer[0];
   outptr = dest->iobuffer;
-  for (col = cinfo->output_width; col > 0; col--) {
-    *outptr++ = (char)GETJSAMPLE(*inptr++);
-  }
+  MEMCOPY(outptr, inptr, cinfo->output_width);
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
 }
 
@@ -147,7 +144,7 @@
   inptr = dest->pub.buffer[0];
   outptr = dest->iobuffer;
   for (col = cinfo->output_width; col > 0; col--) {
-    *outptr++ = (char)GETJSAMPLE(color_map0[GETJSAMPLE(*inptr++)]);
+    *outptr++ = color_map0[*inptr++];
   }
   (void)JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
 }
@@ -182,9 +179,9 @@
       /* Write the colormap.  Note Targa uses BGR byte order */
       outfile = dest->pub.output_file;
       for (i = 0; i < num_colors; i++) {
-        putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile);
-        putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile);
-        putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile);
+        putc(cinfo->colormap[2][i], outfile);
+        putc(cinfo->colormap[1][i], outfile);
+        putc(cinfo->colormap[0][i], outfile);
       }
       dest->pub.put_pixel_rows = put_gray_rows;
     } else {
diff --git a/src/third_party/libxml/src/entities.c b/src/third_party/libxml/src/entities.c
index ea54cc3..4b41fe9 100644
--- a/src/third_party/libxml/src/entities.c
+++ b/src/third_party/libxml/src/entities.c
@@ -667,11 +667,25 @@
 	    } else {
 		/*
 		 * We assume we have UTF-8 input.
+		 * It must match either:
+		 *   110xxxxx 10xxxxxx
+		 *   1110xxxx 10xxxxxx 10xxxxxx
+		 *   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+		 * That is:
+		 *   cur[0] is 11xxxxxx
+		 *   cur[1] is 10xxxxxx
+		 *   cur[2] is 10xxxxxx if cur[0] is 111xxxxx
+		 *   cur[3] is 10xxxxxx if cur[0] is 1111xxxx
+		 *   cur[0] is not 11111xxx
 		 */
 		char buf[11], *ptr;
 		int val = 0, l = 1;
 
-		if (*cur < 0xC0) {
+		if (((cur[0] & 0xC0) != 0xC0) ||
+		    ((cur[1] & 0xC0) != 0x80) ||
+		    (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) ||
+		    (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) ||
+		    (((cur[0] & 0xF8) == 0xF8))) {
 		    xmlEntitiesErr(XML_CHECK_NOT_UTF8,
 			    "xmlEncodeEntities: input not UTF-8");
 		    if (doc != NULL)
diff --git a/src/third_party/skia/src/sksl/SkSLString.cpp b/src/third_party/skia/src/sksl/SkSLString.cpp
index 5cabe9f..b5a2605 100644
--- a/src/third_party/skia/src/sksl/SkSLString.cpp
+++ b/src/third_party/skia/src/sksl/SkSLString.cpp
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <string>
 
+#include "base/strings/string_number_conversions.h"
+
 #if defined(STARBOARD)
 #include "starboard/client_porting/poem/string_poem.h"
 #endif
@@ -229,6 +231,24 @@
 }
 
 String to_string(double value) {
+#if defined(STARBOARD)
+    std::string s = base::NumberToString(value);
+    bool needsDotZero = true;
+    for (int i = s.size() - 1; i >= 0; --i) {
+        char c = s[i];
+        if (c == '.' || c == 'e') {
+            needsDotZero = false;
+            break;
+        }
+    }
+    if (needsDotZero) {
+        s += ".0";
+    }
+    if (s.size() > 0 && s[0] == '.') {
+      s = "0" + s;
+    }
+    return String(s.c_str());
+#else
     std::stringstream buffer;
     buffer.imbue(std::locale::classic());
     buffer.precision(17);
@@ -246,6 +266,7 @@
         buffer << ".0";
     }
     return String(buffer.str().c_str());
+#endif
 }
 
 SKSL_INT stoi(const String& s) {
@@ -258,6 +279,12 @@
 }
 
 SKSL_FLOAT stod(const String& s) {
+#if defined(STARBOARD)
+    double d;
+    bool res= base::StringToDouble(s.c_str(), &d);
+    SkASSERT(res);
+    return d;
+#else
     double result;
     std::string str(s.c_str(), s.size());
     std::stringstream buffer(str);
@@ -265,6 +292,7 @@
     buffer >> result;
     SkASSERT(!buffer.fail());
     return result;
+#endif
 }
 
 long stol(const String& s) {
diff --git a/src/third_party/zlib/BUILD.gn b/src/third_party/zlib/BUILD.gn
index abcbcb4..4c5e6b4 100644
--- a/src/third_party/zlib/BUILD.gn
+++ b/src/third_party/zlib/BUILD.gn
@@ -57,7 +57,9 @@
     ]
     if (!is_debug) {
       # Use optimize_speed (-O3) to output the _smallest_ code.
-      configs -= [ "//build/config/compiler:default_optimization" ]
+      if(!is_starboard) {
+        configs -= [ "//build/config/compiler:default_optimization" ]
+      }
       configs += [ "//build/config/compiler:optimize_speed" ]
     }
   }
@@ -76,7 +78,7 @@
     # Disabled for iPhone, as described in DDI0487C_a_armv8_arm:
     #  "All implementations of the ARMv8.1 architecture are required to
     #   implement the CRC32* instructions. These are optional in ARMv8.0."
-    if (!is_ios) {
+    if (!is_ios && arm_version >= 8) {
       defines = [ "CRC32_ARMV8_CRC32" ]
       if (is_android) {
         defines += [ "ARMV8_OS_ANDROID" ]
@@ -121,7 +123,9 @@
       ]
 
       if (!is_debug) {
-        configs -= [ "//build/config/compiler:default_optimization" ]
+        if(!is_starboard) {
+          configs -= [ "//build/config/compiler:default_optimization" ]
+        }
         configs += [ "//build/config/compiler:optimize_speed" ]
       }
     }
@@ -174,7 +178,9 @@
     if (use_arm_neon_optimizations && !is_debug) {
       # Here we trade better performance on newer/bigger ARMv8 cores
       # for less perf on ARMv7, per crbug.com/772870#c40
-      configs -= [ "//build/config/compiler:default_optimization" ]
+      if(!is_starboard) {
+        configs -= [ "//build/config/compiler:default_optimization" ]
+      }
       configs += [ "//build/config/compiler:optimize_speed" ]
     }
   }
@@ -312,7 +318,10 @@
       cflags_c += [ "-Wno-missing-braces" ]
       deps += [ ":zlib_crc32_simd" ]
     } else if (use_arm_neon_optimizations) {
-      sources += [ "contrib/optimizations/slide_hash_neon.h" ]
+      sources += [
+        "contrib/optimizations/slide_hash_neon.c",
+        "contrib/optimizations/slide_hash_neon.h",
+      ]
       deps += [ ":zlib_arm_crc32" ]
     }
   } else {
diff --git a/src/tools/format_ninja.py b/src/tools/format_ninja.py
index acff046..f18e622 100644
--- a/src/tools/format_ninja.py
+++ b/src/tools/format_ninja.py
@@ -35,6 +35,7 @@
 _ACTION_COMPONENTS = ['directory', 'command', 'file', 'output']
 STRIP = 0
 
+
 def make_path_absolute(path: str, directory: str) -> str:
   if os.path.isabs(path):
     return path
@@ -43,8 +44,9 @@
 
 
 def remove_directory_path(path: str, directory: str) -> str:
-  dirsplit = directory.split(os.path.sep)
-  directory = os.path.sep.join(dirsplit[:-STRIP])
+  if STRIP :
+    dirsplit = directory.split(os.path.sep)
+    directory = os.path.sep.join(dirsplit[:-(STRIP)])
   if os.path.commonpath([path, directory]) != directory:
     return path