WebKit Bugzilla
Attachment 339910 Details for
Bug 185272
: [WebGL] WEBGL_compressed_texture_astc support
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185272-20180508183209.patch (text/plain), 328.33 KB, created by
Justin Fan
on 2018-05-08 18:32:09 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Justin Fan
Created:
2018-05-08 18:32:09 PDT
Size:
328.33 KB
patch
obsolete
>Subversion Revision: 231533 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index b2de2420ee9a62c92458f46180a38604435da8e3..882376be7e50e8baf5b4ab3433e5c2cf07ef03d3 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,41 @@ >+2018-05-03 Justin Fan <justin_fan@apple.com> >+ >+ Hooked up ASTC support in WebGL; requires OpenGL ES 3 context to work. >+ https://bugs.webkit.org/show_bug.cgi?id=185272 >+ <rdar://15745737> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Also added in Khronos' ASTC test from version 1.0.4 beta of their conformance test suite, >+ although again, this requires OpenGL ES 3 context for WebKit to detect proper support. >+ >+ Test: fast/canvas/webgl/webgl-compressed-texture-astc.html >+ >+ * DerivedSources.make: >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * bindings/js/JSDOMConvertWebGL.cpp: >+ (WebCore::convertToJSValue): >+ * html/canvas/WebGL2RenderingContext.cpp: >+ (WebCore::WebGL2RenderingContext::getExtension): >+ (WebCore::WebGL2RenderingContext::getSupportedExtensions): >+ * html/canvas/WebGLCompressedTextureASTC.cpp: Added. >+ (WebCore::WebGLCompressedTextureASTC::WebGLCompressedTextureASTC): >+ (WebCore::WebGLCompressedTextureASTC::getName const): >+ (WebCore::WebGLCompressedTextureASTC::supported): >+ (WebCore::WebGLCompressedTextureASTC::getSupportedProfiles): >+ * html/canvas/WebGLCompressedTextureASTC.h: Added. >+ * html/canvas/WebGLCompressedTextureASTC.idl: Added. >+ * html/canvas/WebGLExtension.h: >+ * html/canvas/WebGLRenderingContext.cpp: >+ (WebCore::WebGLRenderingContext::getExtension): >+ (WebCore::WebGLRenderingContext::getSupportedExtensions): >+ * html/canvas/WebGLRenderingContextBase.cpp: >+ (WebCore::WebGLRenderingContextBase::validateCompressedTexFuncData): >+ (WebCore::WebGLRenderingContextBase::validateCompressedTexDimensions): >+ * html/canvas/WebGLRenderingContextBase.h: >+ * platform/graphics/Extensions3D.h: >+ > 2018-05-08 Ryan Haddad <ryanhaddad@apple.com> > > Unreviewed, rolling out r231486. >diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt >index 23c95bf9681507da7c83c8378c2e608039bf1f32..264414e49a7c15e7cc733ecf7ec954f5123d454f 100644 >--- a/Source/WebCore/CMakeLists.txt >+++ b/Source/WebCore/CMakeLists.txt >@@ -1169,6 +1169,7 @@ if (ENABLE_WEBGL) > html/canvas/OESVertexArrayObject.cpp > html/canvas/WebGL2RenderingContext.cpp > html/canvas/WebGLBuffer.cpp >+ html/canvas/WebGLCompressedTextureASTC.cpp > html/canvas/WebGLCompressedTextureATC.cpp > html/canvas/WebGLCompressedTexturePVRTC.cpp > html/canvas/WebGLCompressedTextureS3TC.cpp >@@ -1217,6 +1218,7 @@ if (ENABLE_WEBGL) > html/canvas/WebGL2RenderingContext.idl > html/canvas/WebGLActiveInfo.idl > html/canvas/WebGLBuffer.idl >+ html/canvas/WebGLCompressedTextureASTC.idl > html/canvas/WebGLCompressedTextureATC.idl > html/canvas/WebGLCompressedTexturePVRTC.idl > html/canvas/WebGLCompressedTextureS3TC.idl >diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make >index ac0b6f1692776c5e4be9a663fd306c277ceb162c..b660e322817f18bfe17bce67bdff01e5cc05d9ce 100644 >--- a/Source/WebCore/DerivedSources.make >+++ b/Source/WebCore/DerivedSources.make >@@ -693,6 +693,7 @@ JS_BINDING_IDLS = \ > $(WebCore)/html/canvas/WebGL2RenderingContext.idl \ > $(WebCore)/html/canvas/WebGLActiveInfo.idl \ > $(WebCore)/html/canvas/WebGLBuffer.idl \ >+ $(WebCore)/html/canvas/WebGLCompressedTextureASTC.idl \ > $(WebCore)/html/canvas/WebGLCompressedTextureATC.idl \ > $(WebCore)/html/canvas/WebGLCompressedTexturePVRTC.idl \ > $(WebCore)/html/canvas/WebGLCompressedTextureS3TC.idl \ >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 94e010a1e3e5ba31474982edba6bcf7ee89f86cb..5d544ee3384ae86cbc69dea70e71e801ff26482b 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -3194,6 +3194,7 @@ JSOESVertexArrayObject.cpp > JSWebGL2RenderingContext.cpp > JSWebGLActiveInfo.cpp > JSWebGLBuffer.cpp >+JSWebGLCompressedTextureASTC.cpp > JSWebGLCompressedTextureATC.cpp > JSWebGLCompressedTexturePVRTC.cpp > JSWebGLCompressedTextureS3TC.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 58600bb6cf6b09050bbcf5f8074a7b78cb704240..b9a9f74287b58a3d1354c6bf1e6753c420d37f40 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -4106,6 +4106,8 @@ > D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */; }; > D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */; }; > D086FE9809D53AAB005BC74D /* UnlinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D086FE9609D53AAB005BC74D /* UnlinkCommand.h */; }; >+ D08B00E220A282490004BC0A /* WebGLCompressedTextureASTC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */; }; >+ D08B00E420A282590004BC0A /* WebGLCompressedTextureASTC.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */; }; > D0A3A7311405A39800FB8ED3 /* ResourceLoaderOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A3A7301405A39800FB8ED3 /* ResourceLoaderOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; > D0B0556809C6700100307E43 /* CreateLinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0B0556609C6700100307E43 /* CreateLinkCommand.h */; }; > D0BC54491443AC4A00E105DA /* CachedStyleSheetClient.h in Headers */ = {isa = PBXBuildFile; fileRef = D0BC54481443AC4A00E105DA /* CachedStyleSheetClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -13471,6 +13473,7 @@ > D01A27AC10C9BFD800026A42 /* SpaceSplitString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceSplitString.h; sourceTree = "<group>"; }; > D02B64B014089E56006EFA21 /* DictationPhraseWithAlternativesDot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = DictationPhraseWithAlternativesDot.png; sourceTree = "<group>"; }; > D02B64B114089E56006EFA21 /* DictationPhraseWithAlternativesDot@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "DictationPhraseWithAlternativesDot@2x.png"; sourceTree = "<group>"; }; >+ D036DD8D208FFC0C00F9F4B2 /* WebGLCompressedTextureASTC.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGLCompressedTextureASTC.idl; sourceTree = "<group>"; }; > D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FormatBlockCommand.cpp; sourceTree = "<group>"; }; > D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FormatBlockCommand.h; sourceTree = "<group>"; }; > D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveFormatCommand.h; sourceTree = "<group>"; }; >@@ -13479,6 +13482,8 @@ > D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InsertListCommand.h; sourceTree = "<group>"; }; > D086FE9609D53AAB005BC74D /* UnlinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkCommand.h; sourceTree = "<group>"; }; > D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkCommand.cpp; sourceTree = "<group>"; }; >+ D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLCompressedTextureASTC.h; sourceTree = "<group>"; }; >+ D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLCompressedTextureASTC.cpp; sourceTree = "<group>"; }; > D0A3A7301405A39800FB8ED3 /* ResourceLoaderOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoaderOptions.h; sourceTree = "<group>"; }; > D0B0556609C6700100307E43 /* CreateLinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CreateLinkCommand.h; sourceTree = "<group>"; }; > D0B0556709C6700100307E43 /* CreateLinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CreateLinkCommand.cpp; sourceTree = "<group>"; }; >@@ -17250,6 +17255,9 @@ > 49C7B9A81042D32E0009D447 /* WebGLBuffer.cpp */, > 49C7B9A91042D32E0009D447 /* WebGLBuffer.h */, > 49C7B9AA1042D32E0009D447 /* WebGLBuffer.idl */, >+ D0A20D562092A0A600E0C259 /* WebGLCompressedTextureASTC.cpp */, >+ D0A20D542092A0A600E0C259 /* WebGLCompressedTextureASTC.h */, >+ D036DD8D208FFC0C00F9F4B2 /* WebGLCompressedTextureASTC.idl */, > 7E66E23116D6EB6C00F7E7FF /* WebGLCompressedTextureATC.cpp */, > 7E66E23216D6EB6C00F7E7FF /* WebGLCompressedTextureATC.h */, > 7EA30F6216DFD62700257D0B /* WebGLCompressedTextureATC.idl */, >@@ -30731,6 +30739,7 @@ > 6E47E66110B7944B00B186C8 /* WebGLAny.h in Headers */, > 1AFFC4581D5E865500267A66 /* WebGLBlacklist.h in Headers */, > 49C7B9C91042D32F0009D447 /* WebGLBuffer.h in Headers */, >+ D08B00E420A282590004BC0A /* WebGLCompressedTextureASTC.h in Headers */, > 7E66E23416D6EB6C00F7E7FF /* WebGLCompressedTextureATC.h in Headers */, > 7E66E23417E6EB6C00F7E7FF /* WebGLCompressedTexturePVRTC.h in Headers */, > 6E3FAE8F14733FDB00E42306 /* WebGLCompressedTextureS3TC.h in Headers */, >@@ -32018,6 +32027,7 @@ > 93F19B0708245E59001E9ABC /* WebCoreView.m in Sources */, > D3F3D36D1A69B7DC0059FC2B /* WebGL2RenderingContext.cpp in Sources */, > 49C7B9C81042D32F0009D447 /* WebGLBuffer.cpp in Sources */, >+ D08B00E220A282490004BC0A /* WebGLCompressedTextureASTC.cpp in Sources */, > 7E66E23316D6EB6C00F7E7FF /* WebGLCompressedTextureATC.cpp in Sources */, > 7E66E23317E6EB6C00F7E7FF /* WebGLCompressedTexturePVRTC.cpp in Sources */, > 6E3FAE8E14733FDB00E42306 /* WebGLCompressedTextureS3TC.cpp in Sources */, >diff --git a/Source/WebCore/bindings/js/JSDOMConvertWebGL.cpp b/Source/WebCore/bindings/js/JSDOMConvertWebGL.cpp >index 126af2ac09b2f9061918bc20a652d91a0c0b8b7e..0b977318dcd08c660a93d3b048c7b0ce2d322d15 100644 >--- a/Source/WebCore/bindings/js/JSDOMConvertWebGL.cpp >+++ b/Source/WebCore/bindings/js/JSDOMConvertWebGL.cpp >@@ -43,6 +43,7 @@ > #include "JSOESTextureHalfFloatLinear.h" > #include "JSOESVertexArrayObject.h" > #include "JSWebGLBuffer.h" >+#include "JSWebGLCompressedTextureASTC.h" > #include "JSWebGLCompressedTextureATC.h" > #include "JSWebGLCompressedTexturePVRTC.h" > #include "JSWebGLCompressedTextureS3TC.h" >@@ -179,6 +180,8 @@ JSValue convertToJSValue(ExecState& state, JSDOMGlobalObject& globalObject, WebG > return toJS(&state, &globalObject, static_cast<WebGLCompressedTexturePVRTC&>(extension)); > case WebGLExtension::WebGLCompressedTextureS3TCName: > return toJS(&state, &globalObject, static_cast<WebGLCompressedTextureS3TC&>(extension)); >+ case WebGLExtension::WebGLCompressedTextureASTCName: >+ return toJS(&state, &globalObject, static_cast<WebGLCompressedTextureASTC&>(extension)); > case WebGLExtension::WebGLDepthTextureName: > return toJS(&state, &globalObject, static_cast<WebGLDepthTexture&>(extension)); > case WebGLExtension::WebGLDrawBuffersName: >diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp >index 5e45bee680fadf2d05b05f4a806f082157056751..d6386aab47ebd97085ac57d209e8c067f5683d94 100644 >--- a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp >+++ b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp >@@ -42,6 +42,7 @@ > #include "OESTextureHalfFloatLinear.h" > #include "RenderBox.h" > #include "WebGLActiveInfo.h" >+#include "WebGLCompressedTextureASTC.h" > #include "WebGLCompressedTextureATC.h" > #include "WebGLCompressedTexturePVRTC.h" > #include "WebGLCompressedTextureS3TC.h" >@@ -1123,6 +1124,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) > ENABLE_IF_REQUESTED(WebGLCompressedTextureATC, m_webglCompressedTextureATC, "WEBKIT_WEBGL_compressed_texture_atc", WebGLCompressedTextureATC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLCompressedTexturePVRTC, m_webglCompressedTexturePVRTC, "WEBKIT_WEBGL_compressed_texture_pvrtc", WebGLCompressedTexturePVRTC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLCompressedTextureS3TC, m_webglCompressedTextureS3TC, "WEBGL_compressed_texture_s3tc", WebGLCompressedTextureS3TC::supported(*this)); >+ ENABLE_IF_REQUESTED(WebGLCompressedTextureASTC, m_webglCompressedTextureASTC, "WEBGL_compressed_texture_astc", WebGLCompressedTextureASTC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLDepthTexture, m_webglDepthTexture, "WEBGL_depth_texture", WebGLDepthTexture::supported(*graphicsContext3D())); > ENABLE_IF_REQUESTED(WebGLDebugRendererInfo, m_webglDebugRendererInfo, "WEBGL_debug_renderer_info", true); > ENABLE_IF_REQUESTED(WebGLDebugShaders, m_webglDebugShaders, "WEBGL_debug_shaders", m_context->getExtensions().supports(ASCIILiteral { "GL_ANGLE_translated_shader_source" })); >@@ -1156,6 +1158,8 @@ std::optional<Vector<String>> WebGL2RenderingContext::getSupportedExtensions() > result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_pvrtc" }); > if (WebGLCompressedTextureS3TC::supported(*this)) > result.append(ASCIILiteral { "WEBGL_compressed_texture_s3tc" }); >+ if (WebGLCompressedTextureASTC::supported(*this)) >+ result.append(ASCIILiteral { "WEBGL_compressed_texture_astc" }); > if (WebGLDepthTexture::supported(*graphicsContext3D())) > result.append(ASCIILiteral { "WEBGL_depth_texture" }); > result.append(ASCIILiteral { "WEBGL_lose_context" }); >diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..9f5bf8680a9606e6c4892ce5f57cfee124926c3c >--- /dev/null >+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.cpp >@@ -0,0 +1,101 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. 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. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "config.h" >+#include "WebGLCompressedTextureASTC.h" >+ >+#if ENABLE(WEBGL) >+ >+#include "Extensions3D.h" >+#include "RuntimeEnabledFeatures.h" >+#include "WebGLRenderingContextBase.h" >+ >+namespace WebCore { >+ >+WebGLCompressedTextureASTC::WebGLCompressedTextureASTC(WebGLRenderingContextBase& context) >+ : WebGLExtension(context) >+ , m_isHDRSupported(context.graphicsContext3D()->getExtensions().supports(ASCIILiteral { "GL_KHR_texture_compression_astc_hdr" })) >+ , m_isLDRSupported(context.graphicsContext3D()->getExtensions().supports(ASCIILiteral { "GL_KHR_texture_compression_astc_ldr" })) >+{ >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_4x4_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_5x4_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_5x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_6x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_6x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_8x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_8x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_8x8_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_10x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_10x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_10x8_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_10x10_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_12x10_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_ASTC_12x12_KHR); >+ >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR); >+ context.addCompressedTextureFormat(Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR); >+} >+ >+WebGLCompressedTextureASTC::~WebGLCompressedTextureASTC() = default; >+ >+WebGLExtension::ExtensionName WebGLCompressedTextureASTC::getName() const >+{ >+ return WebGLCompressedTextureASTCName; >+} >+ >+Vector<String> WebGLCompressedTextureASTC::getSupportedProfiles() >+{ >+ Vector<String> result; >+ >+ if (m_isHDRSupported) >+ result.append(ASCIILiteral { "hdr" }); >+ if (m_isLDRSupported) >+ result.append(ASCIILiteral { "ldr" }); >+ >+ return result; >+} >+ >+bool WebGLCompressedTextureASTC::supported(const WebGLRenderingContextBase& context) >+{ >+ return RuntimeEnabledFeatures::sharedFeatures().webGLCompressedTextureASTCSupportEnabled() >+ && (context.graphicsContext3D()->getExtensions().supports(ASCIILiteral { "GL_KHR_texture_compression_astc_hdr" }) >+ || context.graphicsContext3D()->getExtensions().supports(ASCIILiteral { "GL_KHR_texture_compression_astc_ldr" })); >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBGL) >diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.h b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.h >new file mode 100644 >index 0000000000000000000000000000000000000000..6f0ed3eca74a79a0240de2b57c1b13f4722151fe >--- /dev/null >+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.h >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. 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. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. >+ */ >+ >+#pragma once >+ >+#include "WebGLExtension.h" >+ >+namespace WebCore { >+ >+class WebGLCompressedTextureASTC final : public WebGLExtension { >+public: >+ explicit WebGLCompressedTextureASTC(WebGLRenderingContextBase&); >+ virtual ~WebGLCompressedTextureASTC(); >+ >+ ExtensionName getName() const override; >+ Vector<String> getSupportedProfiles(); >+ >+ static bool supported(const WebGLRenderingContextBase&); >+private: >+ bool m_isHDRSupported : 1; >+ bool m_isLDRSupported : 1; >+}; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.idl b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.idl >new file mode 100644 >index 0000000000000000000000000000000000000000..19213cc36e879ad01a12d733bcbe5d68ae466055 >--- /dev/null >+++ b/Source/WebCore/html/canvas/WebGLCompressedTextureASTC.idl >@@ -0,0 +1,65 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. 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. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. >+ */ >+ >+[ >+ Conditional=WEBGL, >+ DoNotCheckConstants, >+ GenerateIsReachable=ImplWebGLRenderingContext, >+ NoInterfaceObject, >+] interface WebGLCompressedTextureASTC { >+ /* Compressed Texture Format */ >+ const GLenum COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0; >+ const GLenum COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1; >+ const GLenum COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2; >+ const GLenum COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3; >+ const GLenum COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4; >+ const GLenum COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5; >+ const GLenum COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6; >+ const GLenum COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7; >+ const GLenum COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8; >+ const GLenum COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9; >+ const GLenum COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA; >+ const GLenum COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB; >+ const GLenum COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC; >+ const GLenum COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD; >+ >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC; >+ const GLenum COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD; >+ >+ // Profile query support. >+ sequence<DOMString> getSupportedProfiles(); >+}; >diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h >index 7f709b4458037aec71e72a4d724833e919e83dfc..0f601fa82ffd826750e195042c548f49a5ffc287 100644 >--- a/Source/WebCore/html/canvas/WebGLExtension.h >+++ b/Source/WebCore/html/canvas/WebGLExtension.h >@@ -54,6 +54,7 @@ public: > OESElementIndexUintName, > WebGLCompressedTextureATCName, > WebGLCompressedTexturePVRTCName, >+ WebGLCompressedTextureASTCName, > ANGLEInstancedArraysName, > }; > >diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp >index dbc1418595b722ffd6985391173f856aad03114b..a1a51c71704b3a114a9f95712d358a30b8d8defe 100644 >--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp >+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp >@@ -49,6 +49,7 @@ > #include "OESTextureHalfFloatLinear.h" > #include "OESVertexArrayObject.h" > #include "RenderBox.h" >+#include "WebGLCompressedTextureASTC.h" > #include "WebGLCompressedTextureATC.h" > #include "WebGLCompressedTexturePVRTC.h" > #include "WebGLCompressedTextureS3TC.h" >@@ -147,6 +148,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) > ENABLE_IF_REQUESTED(WebGLCompressedTextureATC, m_webglCompressedTextureATC, "WEBKIT_WEBGL_compressed_texture_atc", WebGLCompressedTextureATC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLCompressedTexturePVRTC, m_webglCompressedTexturePVRTC, "WEBKIT_WEBGL_compressed_texture_pvrtc", WebGLCompressedTexturePVRTC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLCompressedTextureS3TC, m_webglCompressedTextureS3TC, "WEBGL_compressed_texture_s3tc", WebGLCompressedTextureS3TC::supported(*this)); >+ ENABLE_IF_REQUESTED(WebGLCompressedTextureASTC, m_webglCompressedTextureASTC, "WEBGL_compressed_texture_astc", WebGLCompressedTextureASTC::supported(*this)); > ENABLE_IF_REQUESTED(WebGLDepthTexture, m_webglDepthTexture, "WEBGL_depth_texture", WebGLDepthTexture::supported(*m_context)); > if (equalIgnoringASCIICase(name, "WEBGL_draw_buffers")) { > if (!m_webglDrawBuffers) { >@@ -217,7 +219,9 @@ std::optional<Vector<String>> WebGLRenderingContext::getSupportedExtensions() > if (WebGLCompressedTexturePVRTC::supported(*this)) > result.append(ASCIILiteral { "WEBKIT_WEBGL_compressed_texture_pvrtc" }); > if (WebGLCompressedTextureS3TC::supported(*this)) >- result.append("WEBGL_compressed_texture_s3tc"); >+ result.append(ASCIILiteral { "WEBGL_compressed_texture_s3tc" }); >+ if (WebGLCompressedTextureASTC::supported(*this)) >+ result.append(ASCIILiteral { "WEBGL_compressed_texture_astc" }); > if (WebGLDepthTexture::supported(*m_context)) > result.append(ASCIILiteral { "WEBGL_depth_texture" }); > if (supportsDrawBuffers()) >diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp >index 0e5bfa12cbb492998a6d6e086538eed5b6cdd0da..9d9c726ff55a3ca4d98a10c6722e6fdaffd6f337 100644 >--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp >+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp >@@ -71,6 +71,7 @@ > #include "WebGL2RenderingContext.h" > #include "WebGLActiveInfo.h" > #include "WebGLBuffer.h" >+#include "WebGLCompressedTextureASTC.h" > #include "WebGLCompressedTextureATC.h" > #include "WebGLCompressedTexturePVRTC.h" > #include "WebGLCompressedTextureS3TC.h" >@@ -5364,14 +5365,46 @@ bool WebGLRenderingContextBase::validateCompressedTexFormat(GC3Denum format) > return m_compressedTextureFormats.contains(format); > } > >+struct BlockParameters { >+ const int width; >+ const int height; >+ const int size; >+}; >+ >+static inline unsigned calculateBytesForASTC(GC3Dsizei width, GC3Dsizei height, const BlockParameters& parameters) >+{ >+ return ((width + parameters.width - 1) / parameters.width) * ((height + parameters.height - 1) / parameters.height) * parameters.size; >+} >+ > bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName, GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView& pixels) > { > if (width < 0 || height < 0) { > synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0"); > return false; > } >- >+ > unsigned bytesRequired = 0; >+ >+ // Block parameters for ASTC formats >+ const int kASTCBlockSize = 16; >+ static const BlockParameters ASTCParameters[] { >+ BlockParameters { 4, 4, kASTCBlockSize }, >+ BlockParameters { 5, 4, kASTCBlockSize }, >+ BlockParameters { 5, 5, kASTCBlockSize }, >+ BlockParameters { 6, 5, kASTCBlockSize }, >+ BlockParameters { 6, 6, kASTCBlockSize }, >+ BlockParameters { 8, 5, kASTCBlockSize }, >+ BlockParameters { 8, 6, kASTCBlockSize }, >+ BlockParameters { 8, 8, kASTCBlockSize }, >+ BlockParameters { 10, 5, kASTCBlockSize }, >+ BlockParameters { 10, 6, kASTCBlockSize }, >+ BlockParameters { 10, 8, kASTCBlockSize }, >+ BlockParameters { 10, 10, kASTCBlockSize }, >+ BlockParameters { 12, 10, kASTCBlockSize }, >+ BlockParameters { 12, 12, kASTCBlockSize } >+ }; >+ const GC3Denum ASTCEnumStartRGBA = Extensions3D::COMPRESSED_RGBA_ASTC_4x4_KHR; >+ const GC3Denum ASTCEnumStartSRGB8 = Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; > > switch (format) { > case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT: >@@ -5417,6 +5450,38 @@ bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functi > bytesRequired = (std::max(width, kBlockWidth) * std::max(height, kBlockHeight) * 2 + 7) / kBlockSize; > } > break; >+ case Extensions3D::COMPRESSED_RGBA_ASTC_4x4_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_5x4_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_5x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_6x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_6x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x8_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x8_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x10_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_12x10_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_12x12_KHR: >+ bytesRequired = calculateBytesForASTC(width, height, ASTCParameters[format - ASTCEnumStartRGBA]); >+ break; >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: >+ bytesRequired = calculateBytesForASTC(width, height, ASTCParameters[format - ASTCEnumStartSRGB8]); >+ break; > default: > synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format"); > return false; >@@ -5459,6 +5524,36 @@ bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* func > return false; > } > return true; >+ case Extensions3D::COMPRESSED_RGBA_ASTC_4x4_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_5x4_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_5x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_6x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_6x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_8x8_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x5_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x6_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x8_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_10x10_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_12x10_KHR: >+ case Extensions3D::COMPRESSED_RGBA_ASTC_12x12_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: >+ case Extensions3D::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: >+ // No height and width restrictions on ASTC. >+ return true; > default: > return false; > } >diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.h b/Source/WebCore/html/canvas/WebGLRenderingContextBase.h >index 9d80382382da814dc4ca72153ecb22e1caaf237e..579883e51e5c21aa0eb8512e7a35b9bc7b703361 100644 >--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.h >+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.h >@@ -71,6 +71,7 @@ class OffscreenCanvas; > class WebGLActiveInfo; > class WebGLContextGroup; > class WebGLContextObject; >+class WebGLCompressedTextureASTC; > class WebGLCompressedTextureATC; > class WebGLCompressedTexturePVRTC; > class WebGLCompressedTextureS3TC; >@@ -366,6 +367,7 @@ protected: > friend class WebGLObject; > friend class OESVertexArrayObject; > friend class WebGLDebugShaders; >+ friend class WebGLCompressedTextureASTC; > friend class WebGLCompressedTextureATC; > friend class WebGLCompressedTexturePVRTC; > friend class WebGLCompressedTextureS3TC; >@@ -591,6 +593,7 @@ protected: > std::unique_ptr<WebGLLoseContext> m_webglLoseContext; > std::unique_ptr<WebGLDebugRendererInfo> m_webglDebugRendererInfo; > std::unique_ptr<WebGLDebugShaders> m_webglDebugShaders; >+ std::unique_ptr<WebGLCompressedTextureASTC> m_webglCompressedTextureASTC; > std::unique_ptr<WebGLCompressedTextureATC> m_webglCompressedTextureATC; > std::unique_ptr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC; > std::unique_ptr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC; >diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h >index 0048fe89faba2abf73ba86a84064a6b73811ffde..eb4613726fa9c755569d59297837342462bb356d 100644 >--- a/Source/WebCore/platform/graphics/Extensions3D.h >+++ b/Source/WebCore/platform/graphics/Extensions3D.h >@@ -70,6 +70,8 @@ public: > // GL_EXT_texture_compression_s3tc > // GL_OES_compressed_ETC1_RGB8_texture > // GL_IMG_texture_compression_pvrtc >+ // GL_KHR_texture_compression_astc_hdr >+ // GL_KHR_texture_compression_astc_ldr > // EXT_texture_filter_anisotropic > // GL_EXT_debug_marker > // GL_ARB_draw_buffers / GL_EXT_draw_buffers >@@ -165,6 +167,37 @@ public: > COMPRESSED_ATC_RGB_AMD = 0x8C92, > COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD = 0x8C93, > COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE, >+ >+ // GL_KHR_texture_compression_astc_hdr >+ COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, >+ COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, >+ COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, >+ COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, >+ COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, >+ COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, >+ COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, >+ COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, >+ COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, >+ COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, >+ COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, >+ COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, >+ COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, >+ COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, >+ >+ COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD, > > // GL_EXT_texture_filter_anisotropic > TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE, >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index c933768b7ef7c8777e75b0e00caea4249943790d..fc324063e73cedd59e81689ca4dfc40d167b14f4 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,20 @@ >+2018-05-03 Justin Fan <justin_fan@apple.com> >+ >+ Added Khronos conformance test for ASTC compressed texture support. >+ https://bugs.webkit.org/show_bug.cgi?id=185272 >+ <rdar://15745737> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This requires OpenGL ES 3 context for WebKit to detect proper support. >+ >+ * fast/canvas/webgl/resources/js-test-post.js: Added. >+ * fast/canvas/webgl/resources/js-test-pre.js: Added. >+ * fast/canvas/webgl/resources/js-test-style.css: Added. >+ * fast/canvas/webgl/resources/webgl-test-utils-khr.js: Added. >+ * fast/canvas/webgl/webgl-compressed-texture-astc-expected.txt: Added. >+ * fast/canvas/webgl/webgl-compressed-texture-astc.html: Added. >+ > 2018-05-08 Daniel Bates <dabates@apple.com> > > Do not apply X-Frame-Options and CSP frame-ancestors to Quick Look-applicable responses in NetworkProcess >diff --git a/LayoutTests/fast/canvas/webgl/resources/js-test-post.js b/LayoutTests/fast/canvas/webgl/resources/js-test-post.js >new file mode 100644 >index 0000000000000000000000000000000000000000..e2e2f6031a91cd165ee1fdc69301793dd8b64c71 >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/resources/js-test-post.js >@@ -0,0 +1,29 @@ >+/* >+** Copyright (c) 2012 The Khronos Group Inc. >+** >+** Permission is hereby granted, free of charge, to any person obtaining a >+** copy of this software and/or associated documentation files (the >+** "Materials"), to deal in the Materials without restriction, including >+** without limitation the rights to use, copy, modify, merge, publish, >+** distribute, sublicense, and/or sell copies of the Materials, and to >+** permit persons to whom the Materials are furnished to do so, subject to >+** the following conditions: >+** >+** The above copyright notice and this permission notice shall be included >+** in all copies or substantial portions of the Materials. >+** >+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. >+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY >+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, >+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE >+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. >+*/ >+ >+shouldBeTrue("successfullyParsed"); >+_addSpan('<br /><span class="pass">TEST COMPLETE</span>'); >+if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole('TEST COMPLETE'); >+} >+notifyFinishedToHarness() >diff --git a/LayoutTests/fast/canvas/webgl/resources/js-test-pre.js b/LayoutTests/fast/canvas/webgl/resources/js-test-pre.js >new file mode 100644 >index 0000000000000000000000000000000000000000..df30a6faba83118f6a21e3c7de4a0bde0aa49542 >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/resources/js-test-pre.js >@@ -0,0 +1,744 @@ >+/* >+** Copyright (c) 2012 The Khronos Group Inc. >+** >+** Permission is hereby granted, free of charge, to any person obtaining a >+** copy of this software and/or associated documentation files (the >+** "Materials"), to deal in the Materials without restriction, including >+** without limitation the rights to use, copy, modify, merge, publish, >+** distribute, sublicense, and/or sell copies of the Materials, and to >+** permit persons to whom the Materials are furnished to do so, subject to >+** the following conditions: >+** >+** The above copyright notice and this permission notice shall be included >+** in all copies or substantial portions of the Materials. >+** >+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. >+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY >+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, >+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE >+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. >+*/ >+ >+(function() { >+ var testHarnessInitialized = false; >+ >+ var initNonKhronosFramework = function() { >+ if (testHarnessInitialized) { >+ return; >+ } >+ testHarnessInitialized = true; >+ >+ /* -- plaform specific code -- */ >+ >+ // WebKit Specific code. Add your code here. >+ if (window.testRunner && !window.layoutTestController) { >+ window.layoutTestController = window.testRunner; >+ } >+ >+ if (window.layoutTestController) { >+ window.layoutTestController.overridePreference("WebKitWebGLEnabled", "1"); >+ window.layoutTestController.dumpAsText(); >+ window.layoutTestController.waitUntilDone(); >+ } >+ if (window.internals) { >+ // The WebKit testing system compares console output. >+ // Because the output of the WebGL Tests is GPU dependent >+ // we turn off console messages. >+ window.console.log = function() { }; >+ window.console.error = function() { }; >+ window.internals.settings.setWebGLErrorsToConsoleEnabled(false); >+ >+ // RAF doesn't work in LayoutTests. Disable it so the tests will >+ // use setTimeout instead. >+ window.requestAnimationFrame = undefined; >+ window.webkitRequestAnimationFrame = undefined; >+ } >+ >+ /* -- end platform specific code --*/ >+ } >+ >+ this.initTestingHarness = function() { >+ initNonKhronosFramework(); >+ } >+}()); >+ >+var getUrlOptions = (function() { >+ var _urlOptionsParsed = false; >+ var _urlOptions = {}; >+ return function() { >+ if (!_urlOptionsParsed) { >+ var s = window.location.href; >+ var q = s.indexOf("?"); >+ var e = s.indexOf("#"); >+ if (e < 0) { >+ e = s.length; >+ } >+ var query = s.substring(q + 1, e); >+ var pairs = query.split("&"); >+ for (var ii = 0; ii < pairs.length; ++ii) { >+ var keyValue = pairs[ii].split("="); >+ var key = keyValue[0]; >+ var value = decodeURIComponent(keyValue[1]); >+ _urlOptions[key] = value; >+ } >+ _urlOptionsParsed = true; >+ } >+ >+ return _urlOptions; >+ } >+})(); >+ >+if (typeof quietMode == 'undefined') { >+ var quietMode = (function() { >+ var _quietModeChecked = false; >+ var _isQuiet = false; >+ return function() { >+ if (!_quietModeChecked) { >+ _isQuiet = (getUrlOptions().quiet == 1); >+ _quietModeChecked = true; >+ } >+ return _isQuiet; >+ } >+ })(); >+} >+ >+function nonKhronosFrameworkNotifyDone() { >+ // WebKit Specific code. Add your code here. >+ if (window.layoutTestController) { >+ window.layoutTestController.notifyDone(); >+ } >+} >+ >+function reportTestResultsToHarness(success, msg) { >+ if (window.parent.webglTestHarness) { >+ window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg); >+ } >+} >+ >+function reportSkippedTestResultsToHarness(success, msg) { >+ if (window.parent.webglTestHarness) { >+ window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg, true); >+ } >+} >+ >+function notifyFinishedToHarness() { >+ if (window.parent.webglTestHarness) { >+ window.parent.webglTestHarness.notifyFinished(window.location.pathname); >+ } >+ if (window.nonKhronosFrameworkNotifyDone) { >+ window.nonKhronosFrameworkNotifyDone(); >+ } >+} >+ >+var _bufferedConsoleLogs = []; >+ >+function _bufferedLogToConsole(msg) >+{ >+ if (_bufferedConsoleLogs) { >+ _bufferedConsoleLogs.push(msg); >+ } else if (window.console) { >+ window.console.log(msg); >+ } >+} >+ >+// Public entry point exposed to many other files. >+function bufferedLogToConsole(msg) >+{ >+ _bufferedLogToConsole(msg); >+} >+ >+// Called implicitly by testFailed(). >+function _flushBufferedLogsToConsole() >+{ >+ if (_bufferedConsoleLogs) { >+ if (window.console) { >+ for (var ii = 0; ii < _bufferedConsoleLogs.length; ++ii) { >+ window.console.log(_bufferedConsoleLogs[ii]); >+ } >+ } >+ _bufferedConsoleLogs = null; >+ } >+} >+ >+var _jsTestPreVerboseLogging = false; >+ >+function enableJSTestPreVerboseLogging() >+{ >+ _jsTestPreVerboseLogging = true; >+} >+ >+function description(msg) >+{ >+ initTestingHarness(); >+ if (msg === undefined) { >+ msg = document.title; >+ } >+ // For MSIE 6 compatibility >+ var span = document.createElement("span"); >+ span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>'; >+ var description = document.getElementById("description"); >+ if (description.firstChild) >+ description.replaceChild(span, description.firstChild); >+ else >+ description.appendChild(span); >+ if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole(msg); >+ } >+} >+ >+function _addSpan(contents) >+{ >+ var span = document.createElement("span"); >+ document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace >+ span.innerHTML = contents + '<br />'; >+} >+ >+function debug(msg) >+{ >+ if (!quietMode()) >+ _addSpan(msg); >+ if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole(msg); >+ } >+} >+ >+function escapeHTML(text) >+{ >+ return text.replace(/&/g, "&").replace(/</g, "<"); >+} >+/** >+ * Defines the exception type for a test failure. >+ * @constructor >+ * @param {string} message The error message. >+ */ >+var TestFailedException = function (message) { >+ this.message = message; >+ this.name = "TestFailedException"; >+}; >+ >+/** >+ * @param {string=} msg >+ */ >+function testPassed(msg) { >+ msg = msg || 'Passed'; >+ if (_currentTestName) >+ msg = _currentTestName + ': ' + msg; >+ >+ reportTestResultsToHarness(true, msg); >+ >+ if (!quietMode()) >+ _addSpan('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>'); >+ if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole('PASS ' + msg); >+ } >+} >+ >+/** >+ * @param {string=} msg >+ */ >+function testFailed(msg) { >+ msg = msg || 'Failed'; >+ if (_currentTestName) >+ msg = _currentTestName + ': ' + msg; >+ >+ reportTestResultsToHarness(false, msg); >+ _addSpan('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>'); >+ _bufferedLogToConsole('FAIL ' + msg); >+ _flushBufferedLogsToConsole(); >+} >+ >+var _currentTestName; >+ >+/** >+ * Sets the current test name for usage within testPassedOptions/testFailedOptions. >+ * @param {string=} name The name to set as the current test name. >+ */ >+function setCurrentTestName(name) >+{ >+ _currentTestName = name; >+} >+ >+/** >+ * Gets the current test name in use within testPassedOptions/testFailedOptions. >+ * @return {string} The name of the current test. >+ */ >+function getCurrentTestName() >+{ >+ return _currentTestName; >+} >+ >+/** >+ * Variation of the testPassed function, with the option to not show (and thus not count) the test's pass result. >+ * @param {string} msg The message to be shown in the pass result. >+ * @param {boolean} addSpan Indicates whether the message will be visible (thus counted in the results) or not. >+ */ >+function testPassedOptions(msg, addSpan) >+{ >+ if (addSpan && !quietMode()) >+ { >+ reportTestResultsToHarness(true, _currentTestName + ": " + msg); >+ _addSpan('<span><span class="pass">PASS</span> ' + escapeHTML(_currentTestName) + ": " + escapeHTML(msg) + '</span>'); >+ } >+ if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole('PASS ' + msg); >+ } >+} >+ >+/** >+ * Report skipped tests. >+ * @param {string} msg The message to be shown in the skip result. >+ * @param {boolean} addSpan Indicates whether the message will be visible (thus counted in the results) or not. >+ */ >+function testSkippedOptions(msg, addSpan) >+{ >+ if (addSpan && !quietMode()) >+ { >+ reportSkippedTestResultsToHarness(true, _currentTestName + ": " + msg); >+ _addSpan('<span><span class="warn">SKIP</span> ' + escapeHTML(_currentTestName) + ": " + escapeHTML(msg) + '</span>'); >+ } >+ if (_jsTestPreVerboseLogging) { >+ _bufferedLogToConsole('SKIP' + msg); >+ } >+} >+ >+/** >+ * Variation of the testFailed function, with the option to throw an exception or not. >+ * @param {string} msg The message to be shown in the fail result. >+ * @param {boolean} exthrow Indicates whether the function will throw a TestFailedException or not. >+ */ >+function testFailedOptions(msg, exthrow) >+{ >+ reportTestResultsToHarness(false, _currentTestName + ": " + msg); >+ _addSpan('<span><span class="fail">FAIL</span> ' + escapeHTML(_currentTestName) + ": " + escapeHTML(msg) + '</span>'); >+ _bufferedLogToConsole('FAIL ' + msg); >+ _flushBufferedLogsToConsole(); >+ if (exthrow) { >+ _currentTestName = ""; //Remembering to set the name of current testcase to empty string. >+ throw new TestFailedException(msg); >+ } >+} >+ >+function areArraysEqual(_a, _b) >+{ >+ try { >+ if (_a.length !== _b.length) >+ return false; >+ for (var i = 0; i < _a.length; i++) >+ if (_a[i] !== _b[i]) >+ return false; >+ } catch (ex) { >+ return false; >+ } >+ return true; >+} >+ >+function isMinusZero(n) >+{ >+ // the only way to tell 0 from -0 in JS is the fact that 1/-0 is >+ // -Infinity instead of Infinity >+ return n === 0 && 1/n < 0; >+} >+ >+function isResultCorrect(_actual, _expected) >+{ >+ if (_expected === 0) >+ return _actual === _expected && (1/_actual) === (1/_expected); >+ if (_actual === _expected) >+ return true; >+ if (typeof(_expected) == "number" && isNaN(_expected)) >+ return typeof(_actual) == "number" && isNaN(_actual); >+ if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])) >+ return areArraysEqual(_actual, _expected); >+ return false; >+} >+ >+function stringify(v) >+{ >+ if (v === 0 && 1/v < 0) >+ return "-0"; >+ else return "" + v; >+} >+ >+function evalAndLog(_a) >+{ >+ if (typeof _a != "string") >+ debug("WARN: tryAndLog() expects a string argument"); >+ >+ // Log first in case things go horribly wrong or this causes a sync event. >+ debug(_a); >+ >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ testFailed(_a + " threw exception " + e); >+ } >+ return _av; >+} >+ >+function shouldBe(_a, _b, quiet) >+{ >+ if (typeof _a != "string" || typeof _b != "string") >+ debug("WARN: shouldBe() expects string arguments"); >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ var _bv = eval(_b); >+ >+ if (exception) >+ testFailed(_a + " should be " + _bv + ". Threw exception " + exception); >+ else if (isResultCorrect(_av, _bv)) { >+ if (!quiet) { >+ testPassed(_a + " is " + _b); >+ } >+ } else if (typeof(_av) == typeof(_bv)) >+ testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + "."); >+ else >+ testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ")."); >+} >+ >+function shouldNotBe(_a, _b, quiet) >+{ >+ if (typeof _a != "string" || typeof _b != "string") >+ debug("WARN: shouldNotBe() expects string arguments"); >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ var _bv = eval(_b); >+ >+ if (exception) >+ testFailed(_a + " should not be " + _bv + ". Threw exception " + exception); >+ else if (!isResultCorrect(_av, _bv)) { >+ if (!quiet) { >+ testPassed(_a + " is not " + _b); >+ } >+ } else >+ testFailed(_a + " should not be " + _bv + "."); >+} >+ >+function shouldBeTrue(_a) { shouldBe(_a, "true"); } >+function shouldBeFalse(_a) { shouldBe(_a, "false"); } >+function shouldBeNaN(_a) { shouldBe(_a, "NaN"); } >+function shouldBeNull(_a) { shouldBe(_a, "null"); } >+ >+function shouldBeEqualToString(a, b) >+{ >+ var unevaledString = '"' + b.replace(/"/g, "\"") + '"'; >+ shouldBe(a, unevaledString); >+} >+ >+function shouldEvaluateTo(actual, expected) { >+ // A general-purpose comparator. 'actual' should be a string to be >+ // evaluated, as for shouldBe(). 'expected' may be any type and will be >+ // used without being eval'ed. >+ if (expected == null) { >+ // Do this before the object test, since null is of type 'object'. >+ shouldBeNull(actual); >+ } else if (typeof expected == "undefined") { >+ shouldBeUndefined(actual); >+ } else if (typeof expected == "function") { >+ // All this fuss is to avoid the string-arg warning from shouldBe(). >+ try { >+ var actualValue = eval(actual); >+ } catch (e) { >+ testFailed("Evaluating " + actual + ": Threw exception " + e); >+ return; >+ } >+ shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'", >+ "'" + expected.toString().replace(/\n/g, "") + "'"); >+ } else if (typeof expected == "object") { >+ shouldBeTrue(actual + " == '" + expected + "'"); >+ } else if (typeof expected == "string") { >+ shouldBe(actual, expected); >+ } else if (typeof expected == "boolean") { >+ shouldBe("typeof " + actual, "'boolean'"); >+ if (expected) >+ shouldBeTrue(actual); >+ else >+ shouldBeFalse(actual); >+ } else if (typeof expected == "number") { >+ shouldBe(actual, stringify(expected)); >+ } else { >+ debug(expected + " is unknown type " + typeof expected); >+ shouldBeTrue(actual, "'" +expected.toString() + "'"); >+ } >+} >+ >+function shouldBeNonZero(_a) >+{ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ if (exception) >+ testFailed(_a + " should be non-zero. Threw exception " + exception); >+ else if (_av != 0) >+ testPassed(_a + " is non-zero."); >+ else >+ testFailed(_a + " should be non-zero. Was " + _av); >+} >+ >+function shouldBeNonNull(_a) >+{ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ if (exception) >+ testFailed(_a + " should be non-null. Threw exception " + exception); >+ else if (_av != null) >+ testPassed(_a + " is non-null."); >+ else >+ testFailed(_a + " should be non-null. Was " + _av); >+} >+ >+function shouldBeUndefined(_a) >+{ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ if (exception) >+ testFailed(_a + " should be undefined. Threw exception " + exception); >+ else if (typeof _av == "undefined") >+ testPassed(_a + " is undefined."); >+ else >+ testFailed(_a + " should be undefined. Was " + _av); >+} >+ >+function shouldBeDefined(_a) >+{ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ if (exception) >+ testFailed(_a + " should be defined. Threw exception " + exception); >+ else if (_av !== undefined) >+ testPassed(_a + " is defined."); >+ else >+ testFailed(_a + " should be defined. Was " + _av); >+} >+ >+function shouldBeLessThanOrEqual(_a, _b) { >+ if (typeof _a != "string" || typeof _b != "string") >+ debug("WARN: shouldBeLessThanOrEqual expects string arguments"); >+ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ var _bv = eval(_b); >+ >+ if (exception) >+ testFailed(_a + " should be <= " + _b + ". Threw exception " + exception); >+ else if (typeof _av == "undefined" || _av > _bv) >+ testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); >+ else >+ testPassed(_a + " is <= " + _b); >+} >+ >+function shouldBeGreaterThanOrEqual(_a, _b) { >+ if (typeof _a != "string" || typeof _b != "string") >+ debug("WARN: shouldBeGreaterThanOrEqual expects string arguments"); >+ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ var _bv = eval(_b); >+ >+ if (exception) >+ testFailed(_a + " should be >= " + _b + ". Threw exception " + exception); >+ else if (typeof _av == "undefined" || _av < _bv) >+ testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); >+ else >+ testPassed(_a + " is >= " + _b); >+} >+ >+function expectTrue(v, msg) { >+ if (v) { >+ testPassed(msg); >+ } else { >+ testFailed(msg); >+ } >+} >+ >+function shouldThrow(_a, _e) >+{ >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ var _ev; >+ if (_e) >+ _ev = eval(_e); >+ >+ if (exception) { >+ if (typeof _e == "undefined" || exception == _ev) >+ testPassed(_a + " threw exception " + exception + "."); >+ else >+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + "."); >+ } else if (typeof _av == "undefined") >+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined."); >+ else >+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + "."); >+} >+ >+function shouldBeType(_a, _type) { >+ var exception; >+ var _av; >+ try { >+ _av = eval(_a); >+ } catch (e) { >+ exception = e; >+ } >+ >+ var _typev = eval(_type); >+ >+ if(_typev === Number){ >+ if(_av instanceof Number){ >+ testPassed(_a + " is an instance of Number"); >+ } >+ else if(typeof(_av) === 'number'){ >+ testPassed(_a + " is an instance of Number"); >+ } >+ else{ >+ testFailed(_a + " is not an instance of Number"); >+ } >+ } >+ else if (_av instanceof _typev) { >+ testPassed(_a + " is an instance of " + _type); >+ } else { >+ testFailed(_a + " is not an instance of " + _type); >+ } >+} >+ >+/** >+ * Shows a message in case expression test fails. >+ * @param {boolean} exp >+ * @param {straing} message >+ */ >+function checkMessage(exp, message) { >+ if ( !exp ) >+ _addSpan('<span><span class="warn">WARNING</span> ' + escapeHTML(_currentTestName) + ": " + escapeHTML(message) + '</span>'); >+} >+ >+function assertMsg(assertion, msg) { >+ if (assertion) { >+ testPassed(msg); >+ } else { >+ testFailed(msg); >+ } >+} >+ >+/** >+ * Variation of the assertMsg function, with the option to not show (and thus not count) the test's pass result, >+ * and throw or not a TestFailedException in case of failure. >+ * @param {boolean} assertion If this is true, means success, else failure. >+ * @param {?string} msg The message to be shown in the result. >+ * @param {boolean} verbose In case of success, determines if the test will show it's result and count in the results. >+ * @param {boolean} exthrow In case of failure, determines if the function will throw a TestFailedException. >+ */ >+function assertMsgOptions(assertion, msg, verbose, exthrow) { >+ if (assertion) { >+ testPassedOptions(msg, verbose); >+ } else { >+ testFailedOptions(msg, exthrow); >+ } >+} >+ >+ >+function webglHarnessCollectGarbage() { >+ if (window.GCController) { >+ window.GCController.collect(); >+ return; >+ } >+ >+ if (window.opera && window.opera.collect) { >+ window.opera.collect(); >+ return; >+ } >+ >+ try { >+ window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) >+ .getInterface(Components.interfaces.nsIDOMWindowUtils) >+ .garbageCollect(); >+ return; >+ } catch(e) {} >+ >+ if (window.gc) { >+ window.gc(); >+ return; >+ } >+ >+ if (window.CollectGarbage) { >+ CollectGarbage(); >+ return; >+ } >+ >+ function gcRec(n) { >+ if (n < 1) >+ return {}; >+ var temp = {i: "ab" + i + (i / 100000)}; >+ temp += "foo"; >+ gcRec(n-1); >+ } >+ for (var i = 0; i < 1000; i++) >+ gcRec(10); >+} >+ >+function finishTest() { >+ successfullyParsed = true; >+ var epilogue = document.createElement("script"); >+ var basePath = ""; >+ var expectedBase = "js-test-pre.js"; >+ var scripts = document.getElementsByTagName('script'); >+ for (var script, i = 0; script = scripts[i]; i++) { >+ var src = script.src; >+ var l = src.length; >+ if (src.substr(l - expectedBase.length) == expectedBase) { >+ basePath = src.substr(0, l - expectedBase.length); >+ break; >+ } >+ } >+ epilogue.src = basePath + "js-test-post.js"; >+ document.body.appendChild(epilogue); >+} >+ >diff --git a/LayoutTests/fast/canvas/webgl/resources/js-test-style.css b/LayoutTests/fast/canvas/webgl/resources/js-test-style.css >new file mode 100644 >index 0000000000000000000000000000000000000000..bb7d5148e5a22212169d14e0fcda2893a0abd718 >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/resources/js-test-style.css >@@ -0,0 +1,17 @@ >+.pass { >+ font-weight: bold; >+ color: green; >+} >+.fail { >+ font-weight: bold; >+ color: red; >+} >+.warn { >+ font-weight: bold; >+ color: yellow; >+ text-shadow: 1px 1px #ff0000 >+} >+#console { >+ white-space: pre-wrap; >+ font-family: monospace; >+} >diff --git a/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils-khr.js b/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils-khr.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0976af316c01b0c798e261617cbc390769be2cc8 >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils-khr.js >@@ -0,0 +1,3259 @@ >+/* >+** Copyright (c) 2012 The Khronos Group Inc. >+** >+** Permission is hereby granted, free of charge, to any person obtaining a >+** copy of this software and/or associated documentation files (the >+** "Materials"), to deal in the Materials without restriction, including >+** without limitation the rights to use, copy, modify, merge, publish, >+** distribute, sublicense, and/or sell copies of the Materials, and to >+** permit persons to whom the Materials are furnished to do so, subject to >+** the following conditions: >+** >+** The above copyright notice and this permission notice shall be included >+** in all copies or substantial portions of the Materials. >+** >+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. >+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY >+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, >+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE >+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. >+*/ >+var WebGLTestUtils = (function() { >+"use strict"; >+ >+/** >+ * Wrapped logging function. >+ * @param {string} msg The message to log. >+ */ >+var log = function(msg) { >+ bufferedLogToConsole(msg); >+}; >+ >+/** >+ * Wrapped logging function. >+ * @param {string} msg The message to log. >+ */ >+var error = function(msg) { >+ // For the time being, diverting this to window.console.log rather >+ // than window.console.error. If anyone cares enough they can >+ // generalize the mechanism in js-test-pre.js. >+ log(msg); >+}; >+ >+/** >+ * Turn off all logging. >+ */ >+var loggingOff = function() { >+ log = function() {}; >+ error = function() {}; >+}; >+ >+/** >+ * Converts a WebGL enum to a string. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} value The enum value. >+ * @return {string} The enum as a string. >+ */ >+var glEnumToString = function(gl, value) { >+ // Avoid returning "NO_ERROR" if the arguments are totally wrong. >+ if (gl.NO_ERROR === undefined || value === undefined) { >+ return undefined; >+ } >+ // Optimization for the most common enum: >+ if (value === gl.NO_ERROR) { >+ return "NO_ERROR"; >+ } >+ for (var p in gl) { >+ if (gl[p] == value) { >+ if (p == 'drawingBufferWidth' || p == 'drawingBufferHeight') { >+ continue; >+ } >+ return p; >+ } >+ } >+ return "0x" + Number(value).toString(16); >+}; >+ >+var lastError = ""; >+ >+/** >+ * Returns the last compiler/linker error. >+ * @return {string} The last compiler/linker error. >+ */ >+var getLastError = function() { >+ return lastError; >+}; >+ >+/** >+ * Whether a haystack ends with a needle. >+ * @param {string} haystack String to search >+ * @param {string} needle String to search for. >+ * @param {boolean} True if haystack ends with needle. >+ */ >+var endsWith = function(haystack, needle) { >+ return haystack.substr(haystack.length - needle.length) === needle; >+}; >+ >+/** >+ * Whether a haystack starts with a needle. >+ * @param {string} haystack String to search >+ * @param {string} needle String to search for. >+ * @param {boolean} True if haystack starts with needle. >+ */ >+var startsWith = function(haystack, needle) { >+ return haystack.substr(0, needle.length) === needle; >+}; >+ >+/** >+ * A vertex shader for a single texture. >+ * @type {string} >+ */ >+var simpleTextureVertexShader = [ >+ 'attribute vec4 vPosition;', >+ 'attribute vec2 texCoord0;', >+ 'varying vec2 texCoord;', >+ 'void main() {', >+ ' gl_Position = vPosition;', >+ ' texCoord = texCoord0;', >+ '}'].join('\n'); >+ >+/** >+ * A fragment shader for a single texture. >+ * @type {string} >+ */ >+var simpleTextureFragmentShader = [ >+ 'precision mediump float;', >+ 'uniform sampler2D tex;', >+ 'varying vec2 texCoord;', >+ 'void main() {', >+ ' gl_FragData[0] = texture2D(tex, texCoord);', >+ '}'].join('\n'); >+ >+/** >+ * A fragment shader for a single cube map texture. >+ * @type {string} >+ */ >+var simpleCubeMapTextureFragmentShader = [ >+ 'precision mediump float;', >+ 'uniform samplerCube tex;', >+ 'uniform highp int face;', >+ 'varying vec2 texCoord;', >+ 'void main() {', >+ // Transform [0, 1] -> [-1, 1] >+ ' vec2 texC2 = (texCoord * 2.) - 1.;', >+ // Transform 2d tex coord. to each face of TEXTURE_CUBE_MAP coord. >+ ' vec3 texCube = vec3(0., 0., 0.);', >+ ' if (face == 34069) {', // TEXTURE_CUBE_MAP_POSITIVE_X >+ ' texCube = vec3(1., -texC2.y, -texC2.x);', >+ ' } else if (face == 34070) {', // TEXTURE_CUBE_MAP_NEGATIVE_X >+ ' texCube = vec3(-1., -texC2.y, texC2.x);', >+ ' } else if (face == 34071) {', // TEXTURE_CUBE_MAP_POSITIVE_Y >+ ' texCube = vec3(texC2.x, 1., texC2.y);', >+ ' } else if (face == 34072) {', // TEXTURE_CUBE_MAP_NEGATIVE_Y >+ ' texCube = vec3(texC2.x, -1., -texC2.y);', >+ ' } else if (face == 34073) {', // TEXTURE_CUBE_MAP_POSITIVE_Z >+ ' texCube = vec3(texC2.x, -texC2.y, 1.);', >+ ' } else if (face == 34074) {', // TEXTURE_CUBE_MAP_NEGATIVE_Z >+ ' texCube = vec3(-texC2.x, -texC2.y, -1.);', >+ ' }', >+ ' gl_FragData[0] = textureCube(tex, texCube);', >+ '}'].join('\n'); >+ >+/** >+ * A vertex shader for a single texture. >+ * @type {string} >+ */ >+var noTexCoordTextureVertexShader = [ >+ 'attribute vec4 vPosition;', >+ 'varying vec2 texCoord;', >+ 'void main() {', >+ ' gl_Position = vPosition;', >+ ' texCoord = vPosition.xy * 0.5 + 0.5;', >+ '}'].join('\n'); >+ >+/** >+ * A vertex shader for a uniform color. >+ * @type {string} >+ */ >+var simpleVertexShader = [ >+ 'attribute vec4 vPosition;', >+ 'void main() {', >+ ' gl_Position = vPosition;', >+ '}'].join('\n'); >+ >+/** >+ * A fragment shader for a uniform color. >+ * @type {string} >+ */ >+var simpleColorFragmentShader = [ >+ 'precision mediump float;', >+ 'uniform vec4 u_color;', >+ 'void main() {', >+ ' gl_FragData[0] = u_color;', >+ '}'].join('\n'); >+ >+/** >+ * A fragment shader for a uniform color. >+ * @type {string} >+ */ >+var simpleColorFragmentShaderESSL300 = [ >+ '#version 300 es', >+ 'precision mediump float;', >+ 'out vec4 out_color;', >+ 'uniform vec4 u_color;', >+ 'void main() {', >+ ' out_color = u_color;', >+ '}'].join('\n'); >+ >+/** >+ * A vertex shader for vertex colors. >+ * @type {string} >+ */ >+var simpleVertexColorVertexShader = [ >+ 'attribute vec4 vPosition;', >+ 'attribute vec4 a_color;', >+ 'varying vec4 v_color;', >+ 'void main() {', >+ ' gl_Position = vPosition;', >+ ' v_color = a_color;', >+ '}'].join('\n'); >+ >+/** >+ * A fragment shader for vertex colors. >+ * @type {string} >+ */ >+var simpleVertexColorFragmentShader = [ >+ 'precision mediump float;', >+ 'varying vec4 v_color;', >+ 'void main() {', >+ ' gl_FragData[0] = v_color;', >+ '}'].join('\n'); >+ >+/** >+ * Creates a program, attaches shaders, binds attrib locations, links the >+ * program and calls useProgram. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<!WebGLShader|string>} shaders The shaders to >+ * attach, or the source, or the id of a script to get >+ * the source from. >+ * @param {!Array.<string>} opt_attribs The attribs names. >+ * @param {!Array.<number>} opt_locations The locations for the attribs. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ */ >+var setupProgram = function( >+ gl, shaders, opt_attribs, opt_locations, opt_logShaders) { >+ var realShaders = []; >+ var program = gl.createProgram(); >+ var shaderCount = 0; >+ for (var ii = 0; ii < shaders.length; ++ii) { >+ var shader = shaders[ii]; >+ var shaderType = undefined; >+ if (typeof shader == 'string') { >+ var element = document.getElementById(shader); >+ if (element) { >+ if (element.type != "x-shader/x-vertex" && element.type != "x-shader/x-fragment") >+ shaderType = ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER; >+ shader = loadShaderFromScript(gl, shader, shaderType, undefined, opt_logShaders); >+ } else if (endsWith(shader, ".vert")) { >+ shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER, undefined, opt_logShaders); >+ } else if (endsWith(shader, ".frag")) { >+ shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER, undefined, opt_logShaders); >+ } else { >+ shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER, undefined, opt_logShaders); >+ } >+ } else if (opt_logShaders) { >+ throw 'Shader source logging requested but no shader source provided'; >+ } >+ if (shader) { >+ ++shaderCount; >+ gl.attachShader(program, shader); >+ } >+ } >+ if (shaderCount != 2) { >+ error("Error in compiling shader"); >+ return null; >+ } >+ if (opt_attribs) { >+ for (var ii = 0; ii < opt_attribs.length; ++ii) { >+ gl.bindAttribLocation( >+ program, >+ opt_locations ? opt_locations[ii] : ii, >+ opt_attribs[ii]); >+ } >+ } >+ gl.linkProgram(program); >+ >+ // Check the link status >+ var linked = gl.getProgramParameter(program, gl.LINK_STATUS); >+ if (!linked) { >+ // something went wrong with the link >+ lastError = gl.getProgramInfoLog (program); >+ error("Error in program linking:" + lastError); >+ >+ gl.deleteProgram(program); >+ return null; >+ } >+ >+ gl.useProgram(program); >+ return program; >+}; >+ >+/** >+ * Creates a program, attaches shader, sets up trasnform feedback varyings, >+ * binds attrib locations, links the program and calls useProgram. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<!WebGLShader|string>} shaders The shaders to >+ * attach, or the source, or the id of a script to get >+ * the source from. >+ * @param {!Array.<string>} varyings The transform feedback varying names. >+ * @param {number} bufferMode The mode used to capture the varying variables. >+ * @param {!Array.<string>} opt_attribs The attribs names. >+ * @param {!Array.<number>} opt_locations The locations for the attribs. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ */ >+var setupTransformFeedbackProgram = function( >+ gl, shaders, varyings, bufferMode, opt_attribs, opt_locations, opt_logShaders, opt_skipCompileStatus) { >+ var realShaders = []; >+ var program = gl.createProgram(); >+ var shaderCount = 0; >+ for (var ii = 0; ii < shaders.length; ++ii) { >+ var shader = shaders[ii]; >+ var shaderType = undefined; >+ if (typeof shader == 'string') { >+ var element = document.getElementById(shader); >+ if (element) { >+ if (element.type != "x-shader/x-vertex" && element.type != "x-shader/x-fragment") >+ shaderType = ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER; >+ shader = loadShaderFromScript(gl, shader, shaderType, undefined, opt_logShaders, opt_skipCompileStatus); >+ } else if (endsWith(shader, ".vert")) { >+ shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER, undefined, opt_logShaders, opt_skipCompileStatus); >+ } else if (endsWith(shader, ".frag")) { >+ shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER, undefined, opt_logShaders, opt_skipCompileStatus); >+ } else { >+ shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER, undefined, opt_logShaders, undefined, undefined, opt_skipCompileStatus); >+ } >+ } else if (opt_logShaders) { >+ throw 'Shader source logging requested but no shader source provided'; >+ } >+ if (shader) { >+ ++shaderCount; >+ gl.attachShader(program, shader); >+ } >+ } >+ if (shaderCount != 2) { >+ error("Error in compiling shader"); >+ return null; >+ } >+ >+ if (opt_attribs) { >+ for (var ii = 0; ii < opt_attribs.length; ++ii) { >+ gl.bindAttribLocation( >+ program, >+ opt_locations ? opt_locations[ii] : ii, >+ opt_attribs[ii]); >+ } >+ } >+ >+ gl.transformFeedbackVaryings(program, varyings, bufferMode); >+ >+ gl.linkProgram(program); >+ >+ // Check the link status >+ var linked = gl.getProgramParameter(program, gl.LINK_STATUS); >+ if (!linked) { >+ // something went wrong with the link >+ lastError = gl.getProgramInfoLog (program); >+ error("Error in program linking:" + lastError); >+ >+ gl.deleteProgram(program); >+ return null; >+ } >+ >+ gl.useProgram(program); >+ return program; >+}; >+ >+/** >+ * Creates a simple texture program. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @return {WebGLProgram} >+ */ >+var setupNoTexCoordTextureProgram = function(gl) { >+ return setupProgram(gl, >+ [noTexCoordTextureVertexShader, simpleTextureFragmentShader], >+ ['vPosition'], >+ [0]); >+}; >+ >+/** >+ * Creates a simple texture program. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_texcoordLocation The attrib location for texture coords. >+ * @return {WebGLProgram} >+ */ >+var setupSimpleTextureProgram = function( >+ gl, opt_positionLocation, opt_texcoordLocation) { >+ opt_positionLocation = opt_positionLocation || 0; >+ opt_texcoordLocation = opt_texcoordLocation || 1; >+ return setupProgram(gl, >+ [simpleTextureVertexShader, simpleTextureFragmentShader], >+ ['vPosition', 'texCoord0'], >+ [opt_positionLocation, opt_texcoordLocation]); >+}; >+ >+/** >+ * Creates a simple cube map texture program. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_texcoordLocation The attrib location for texture coords. >+ * @return {WebGLProgram} >+ */ >+var setupSimpleCubeMapTextureProgram = function( >+ gl, opt_positionLocation, opt_texcoordLocation) { >+ opt_positionLocation = opt_positionLocation || 0; >+ opt_texcoordLocation = opt_texcoordLocation || 1; >+ return setupProgram(gl, >+ [simpleTextureVertexShader, simpleCubeMapTextureFragmentShader], >+ ['vPosition', 'texCoord0'], >+ [opt_positionLocation, opt_texcoordLocation]); >+}; >+ >+/** >+ * Creates a simple vertex color program. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_vertexColorLocation The attrib location >+ * for vertex colors. >+ * @return {WebGLProgram} >+ */ >+var setupSimpleVertexColorProgram = function( >+ gl, opt_positionLocation, opt_vertexColorLocation) { >+ opt_positionLocation = opt_positionLocation || 0; >+ opt_vertexColorLocation = opt_vertexColorLocation || 1; >+ return setupProgram(gl, >+ [simpleVertexColorVertexShader, simpleVertexColorFragmentShader], >+ ['vPosition', 'a_color'], >+ [opt_positionLocation, opt_vertexColorLocation]); >+}; >+ >+/** >+ * Creates a simple color program. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @return {WebGLProgram} >+ */ >+var setupSimpleColorProgram = function(gl, opt_positionLocation) { >+ opt_positionLocation = opt_positionLocation || 0; >+ return setupProgram(gl, >+ [simpleVertexShader, simpleColorFragmentShader], >+ ['vPosition'], >+ [opt_positionLocation]); >+}; >+ >+/** >+ * Creates buffers for a textured unit quad and attaches them to vertex attribs. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_texcoordLocation The attrib location for texture coords. >+ * @param {!Object} various options. See setupQuad for details. >+ * @return {!Array.<WebGLBuffer>} The buffer objects that were >+ * created. >+ */ >+var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation, options) { >+ return setupQuadWithTexCoords(gl, [ 0.0, 0.0 ], [ 1.0, 1.0 ], >+ opt_positionLocation, opt_texcoordLocation, >+ options); >+}; >+ >+/** >+ * Creates buffers for a textured quad with specified lower left >+ * and upper right texture coordinates, and attaches them to vertex >+ * attribs. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} lowerLeftTexCoords The texture coordinates for the lower left corner. >+ * @param {!Array.<number>} upperRightTexCoords The texture coordinates for the upper right corner. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_texcoordLocation The attrib location for texture coords. >+ * @param {!Object} various options. See setupQuad for details. >+ * @return {!Array.<WebGLBuffer>} The buffer objects that were >+ * created. >+ */ >+var setupQuadWithTexCoords = function( >+ gl, lowerLeftTexCoords, upperRightTexCoords, >+ opt_positionLocation, opt_texcoordLocation, options) { >+ var defaultOptions = { >+ positionLocation: opt_positionLocation || 0, >+ texcoordLocation: opt_texcoordLocation || 1, >+ lowerLeftTexCoords: lowerLeftTexCoords, >+ upperRightTexCoords: upperRightTexCoords >+ }; >+ if (options) { >+ for (var prop in options) { >+ defaultOptions[prop] = options[prop] >+ } >+ } >+ return setupQuad(gl, defaultOptions); >+}; >+ >+/** >+ * Makes a quad with various options. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Object} options >+ * >+ * scale: scale to multiply unit quad values by. default 1.0. >+ * positionLocation: attribute location for position. >+ * texcoordLocation: attribute location for texcoords. >+ * If this does not exist no texture coords are created. >+ * lowerLeftTexCoords: an array of 2 values for the >+ * lowerLeftTexCoords. >+ * upperRightTexCoords: an array of 2 values for the >+ * upperRightTexCoords. >+ */ >+var setupQuad = function(gl, options) { >+ var positionLocation = options.positionLocation || 0; >+ var scale = options.scale || 1; >+ >+ var objects = []; >+ >+ var vertexObject = gl.createBuffer(); >+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); >+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ >+ 1.0 * scale , 1.0 * scale, >+ -1.0 * scale , 1.0 * scale, >+ -1.0 * scale , -1.0 * scale, >+ 1.0 * scale , 1.0 * scale, >+ -1.0 * scale , -1.0 * scale, >+ 1.0 * scale , -1.0 * scale]), gl.STATIC_DRAW); >+ gl.enableVertexAttribArray(positionLocation); >+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); >+ objects.push(vertexObject); >+ >+ if (options.texcoordLocation !== undefined) { >+ var llx = options.lowerLeftTexCoords[0]; >+ var lly = options.lowerLeftTexCoords[1]; >+ var urx = options.upperRightTexCoords[0]; >+ var ury = options.upperRightTexCoords[1]; >+ >+ vertexObject = gl.createBuffer(); >+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); >+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ >+ urx, ury, >+ llx, ury, >+ llx, lly, >+ urx, ury, >+ llx, lly, >+ urx, lly]), gl.STATIC_DRAW); >+ gl.enableVertexAttribArray(options.texcoordLocation); >+ gl.vertexAttribPointer(options.texcoordLocation, 2, gl.FLOAT, false, 0, 0); >+ objects.push(vertexObject); >+ } >+ >+ return objects; >+}; >+ >+/** >+ * Creates a program and buffers for rendering a textured quad. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for >+ * position. Default = 0. >+ * @param {number} opt_texcoordLocation The attrib location for >+ * texture coords. Default = 1. >+ * @param {!Object} various options. See setupQuad for details. >+ * @return {!WebGLProgram} >+ */ >+var setupTexturedQuad = function( >+ gl, opt_positionLocation, opt_texcoordLocation, options) { >+ var program = setupSimpleTextureProgram( >+ gl, opt_positionLocation, opt_texcoordLocation); >+ setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation, options); >+ return program; >+}; >+ >+/** >+ * Creates a program and buffers for rendering a color quad. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {!Object} various options. See setupQuad for details. >+ * @return {!WebGLProgram} >+ */ >+var setupColorQuad = function(gl, opt_positionLocation, options) { >+ opt_positionLocation = opt_positionLocation || 0; >+ var program = setupSimpleColorProgram(gl, opt_positionLocation); >+ setupUnitQuad(gl, opt_positionLocation, 0, options); >+ return program; >+}; >+ >+/** >+ * Creates a program and buffers for rendering a textured quad with >+ * specified lower left and upper right texture coordinates. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} lowerLeftTexCoords The texture coordinates for the lower left corner. >+ * @param {!Array.<number>} upperRightTexCoords The texture coordinates for the upper right corner. >+ * @param {number} opt_positionLocation The attrib location for position. >+ * @param {number} opt_texcoordLocation The attrib location for texture coords. >+ * @return {!WebGLProgram} >+ */ >+var setupTexturedQuadWithTexCoords = function( >+ gl, lowerLeftTexCoords, upperRightTexCoords, >+ opt_positionLocation, opt_texcoordLocation) { >+ var program = setupSimpleTextureProgram( >+ gl, opt_positionLocation, opt_texcoordLocation); >+ setupQuadWithTexCoords(gl, lowerLeftTexCoords, upperRightTexCoords, >+ opt_positionLocation, opt_texcoordLocation); >+ return program; >+}; >+ >+/** >+ * Creates a program and buffers for rendering a textured quad with >+ * a cube map texture. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} opt_positionLocation The attrib location for >+ * position. Default = 0. >+ * @param {number} opt_texcoordLocation The attrib location for >+ * texture coords. Default = 1. >+ * @return {!WebGLProgram} >+ */ >+var setupTexturedQuadWithCubeMap = function( >+ gl, opt_positionLocation, opt_texcoordLocation) { >+ var program = setupSimpleCubeMapTextureProgram( >+ gl, opt_positionLocation, opt_texcoordLocation); >+ setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation, undefined); >+ return program; >+}; >+ >+/** >+ * Creates a unit quad with only positions of a given resolution. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} gridRes The resolution of the mesh grid, >+ * expressed in the number of quads across and down. >+ * @param {number} opt_positionLocation The attrib location for position. >+ */ >+var setupIndexedQuad = function ( >+ gl, gridRes, opt_positionLocation, opt_flipOddTriangles) { >+ return setupIndexedQuadWithOptions(gl, >+ { gridRes: gridRes, >+ positionLocation: opt_positionLocation, >+ flipOddTriangles: opt_flipOddTriangles >+ }); >+}; >+ >+/** >+ * Creates a quad with various options. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Object} options The options. See below. >+ * @return {!Array.<WebGLBuffer>} The created buffers. >+ * [positions, <colors>, indices] >+ * >+ * Options: >+ * gridRes: number of quads across and down grid. >+ * positionLocation: attrib location for position >+ * flipOddTriangles: reverse order of vertices of every other >+ * triangle >+ * positionOffset: offset added to each vertex >+ * positionMult: multipier for each vertex >+ * colorLocation: attrib location for vertex colors. If >+ * undefined no vertex colors will be created. >+ */ >+var setupIndexedQuadWithOptions = function (gl, options) { >+ var positionLocation = options.positionLocation || 0; >+ var objects = []; >+ >+ var gridRes = options.gridRes || 1; >+ var positionOffset = options.positionOffset || 0; >+ var positionMult = options.positionMult || 1; >+ var vertsAcross = gridRes + 1; >+ var numVerts = vertsAcross * vertsAcross; >+ var positions = new Float32Array(numVerts * 3); >+ var indices = new Uint16Array(6 * gridRes * gridRes); >+ var poffset = 0; >+ >+ for (var yy = 0; yy <= gridRes; ++yy) { >+ for (var xx = 0; xx <= gridRes; ++xx) { >+ positions[poffset + 0] = (-1 + 2 * xx / gridRes) * positionMult + positionOffset; >+ positions[poffset + 1] = (-1 + 2 * yy / gridRes) * positionMult + positionOffset; >+ positions[poffset + 2] = 0; >+ >+ poffset += 3; >+ } >+ } >+ >+ var buf = gl.createBuffer(); >+ gl.bindBuffer(gl.ARRAY_BUFFER, buf); >+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW); >+ gl.enableVertexAttribArray(positionLocation); >+ gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0); >+ objects.push(buf); >+ >+ if (options.colorLocation !== undefined) { >+ var colors = new Float32Array(numVerts * 4); >+ for (var yy = 0; yy <= gridRes; ++yy) { >+ for (var xx = 0; xx <= gridRes; ++xx) { >+ if (options.color !== undefined) { >+ colors[poffset + 0] = options.color[0]; >+ colors[poffset + 1] = options.color[1]; >+ colors[poffset + 2] = options.color[2]; >+ colors[poffset + 3] = options.color[3]; >+ } else { >+ colors[poffset + 0] = xx / gridRes; >+ colors[poffset + 1] = yy / gridRes; >+ colors[poffset + 2] = (xx / gridRes) * (yy / gridRes); >+ colors[poffset + 3] = (yy % 2) * 0.5 + 0.5; >+ } >+ poffset += 4; >+ } >+ } >+ >+ buf = gl.createBuffer(); >+ gl.bindBuffer(gl.ARRAY_BUFFER, buf); >+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); >+ gl.enableVertexAttribArray(options.colorLocation); >+ gl.vertexAttribPointer(options.colorLocation, 4, gl.FLOAT, false, 0, 0); >+ objects.push(buf); >+ } >+ >+ var tbase = 0; >+ for (var yy = 0; yy < gridRes; ++yy) { >+ var index = yy * vertsAcross; >+ for (var xx = 0; xx < gridRes; ++xx) { >+ indices[tbase + 0] = index + 0; >+ indices[tbase + 1] = index + 1; >+ indices[tbase + 2] = index + vertsAcross; >+ indices[tbase + 3] = index + vertsAcross; >+ indices[tbase + 4] = index + 1; >+ indices[tbase + 5] = index + vertsAcross + 1; >+ >+ if (options.flipOddTriangles) { >+ indices[tbase + 4] = index + vertsAcross + 1; >+ indices[tbase + 5] = index + 1; >+ } >+ >+ index += 1; >+ tbase += 6; >+ } >+ } >+ >+ buf = gl.createBuffer(); >+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf); >+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); >+ objects.push(buf); >+ >+ return objects; >+}; >+ >+/** >+ * Returns the constructor for a typed array that corresponds to the given >+ * WebGL type. >+ * @param {!WebGLRenderingContext} gl A WebGLRenderingContext. >+ * @param {number} type The WebGL type (eg, gl.UNSIGNED_BYTE) >+ * @return {!Constructor} The typed array constructor that >+ * corresponds to the given type. >+ */ >+var glTypeToTypedArrayType = function(gl, type) { >+ switch (type) { >+ case gl.BYTE: >+ return window.Int8Array; >+ case gl.UNSIGNED_BYTE: >+ return window.Uint8Array; >+ case gl.SHORT: >+ return window.Int16Array; >+ case gl.UNSIGNED_SHORT: >+ case gl.UNSIGNED_SHORT_5_6_5: >+ case gl.UNSIGNED_SHORT_4_4_4_4: >+ case gl.UNSIGNED_SHORT_5_5_5_1: >+ return window.Uint16Array; >+ case gl.INT: >+ return window.Int32Array; >+ case gl.UNSIGNED_INT: >+ case gl.UNSIGNED_INT_5_9_9_9_REV: >+ case gl.UNSIGNED_INT_10F_11F_11F_REV: >+ case gl.UNSIGNED_INT_2_10_10_10_REV: >+ case gl.UNSIGNED_INT_24_8: >+ return window.Uint32Array; >+ case gl.HALF_FLOAT: >+ case 0x8D61: // HALF_FLOAT_OES >+ return window.Uint16Array; >+ case gl.FLOAT: >+ return window.Float32Array; >+ default: >+ throw 'unknown gl type ' + glEnumToString(gl, type); >+ } >+}; >+ >+/** >+ * Returns the number of bytes per component for a given WebGL type. >+ * @param {!WebGLRenderingContext} gl A WebGLRenderingContext. >+ * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE) >+ * @return {number} The number of bytes per component. >+ */ >+var getBytesPerComponent = function(gl, type) { >+ switch (type) { >+ case gl.BYTE: >+ case gl.UNSIGNED_BYTE: >+ return 1; >+ case gl.SHORT: >+ case gl.UNSIGNED_SHORT: >+ case gl.UNSIGNED_SHORT_5_6_5: >+ case gl.UNSIGNED_SHORT_4_4_4_4: >+ case gl.UNSIGNED_SHORT_5_5_5_1: >+ case gl.HALF_FLOAT: >+ case 0x8D61: // HALF_FLOAT_OES >+ return 2; >+ case gl.INT: >+ case gl.UNSIGNED_INT: >+ case gl.UNSIGNED_INT_5_9_9_9_REV: >+ case gl.UNSIGNED_INT_10F_11F_11F_REV: >+ case gl.UNSIGNED_INT_2_10_10_10_REV: >+ case gl.UNSIGNED_INT_24_8: >+ case gl.FLOAT: >+ return 4; >+ default: >+ throw 'unknown gl type ' + glEnumToString(gl, type); >+ } >+}; >+ >+/** >+ * Returns the number of typed array elements per pixel for a given WebGL >+ * format/type combination. The corresponding typed array type can be determined >+ * by calling glTypeToTypedArrayType. >+ * @param {!WebGLRenderingContext} gl A WebGLRenderingContext. >+ * @param {GLenum} format The WebGL format (eg, gl.RGBA) >+ * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE) >+ * @return {number} The number of typed array elements per pixel. >+ */ >+var getTypedArrayElementsPerPixel = function(gl, format, type) { >+ switch (type) { >+ case gl.UNSIGNED_SHORT_5_6_5: >+ case gl.UNSIGNED_SHORT_4_4_4_4: >+ case gl.UNSIGNED_SHORT_5_5_5_1: >+ return 1; >+ case gl.UNSIGNED_BYTE: >+ break; >+ default: >+ throw 'not a gl type for color information ' + glEnumToString(gl, type); >+ } >+ >+ switch (format) { >+ case gl.RGBA: >+ return 4; >+ case gl.RGB: >+ return 3; >+ case gl.LUMINANCE_ALPHA: >+ return 2; >+ case gl.LUMINANCE: >+ case gl.ALPHA: >+ return 1; >+ default: >+ throw 'unknown gl format ' + glEnumToString(gl, format); >+ } >+}; >+ >+/** >+ * Fills the given texture with a solid color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!WebGLTexture} tex The texture to fill. >+ * @param {number} width The width of the texture to create. >+ * @param {number} height The height of the texture to create. >+ * @param {!Array.<number>} color The color to fill with. >+ * where each element is in the range 0 to 255. >+ * @param {number} opt_level The level of the texture to fill. Default = 0. >+ * @param {number} opt_format The format for the texture. >+ * @param {number} opt_internalFormat The internal format for the texture. >+ */ >+var fillTexture = function(gl, tex, width, height, color, opt_level, opt_format, opt_type, opt_internalFormat) { >+ opt_level = opt_level || 0; >+ opt_format = opt_format || gl.RGBA; >+ opt_type = opt_type || gl.UNSIGNED_BYTE; >+ opt_internalFormat = opt_internalFormat || opt_format; >+ var pack = gl.getParameter(gl.UNPACK_ALIGNMENT); >+ var numComponents = color.length; >+ var bytesPerComponent = getBytesPerComponent(gl, opt_type); >+ var rowSize = numComponents * width * bytesPerComponent; >+ // See equation 3.10 in ES 2.0 spec and equation 3.13 in ES 3.0 spec for paddedRowLength calculation. >+ // k is paddedRowLength. >+ // n is numComponents. >+ // l is width. >+ // a is pack. >+ // s is bytesPerComponent. >+ var paddedRowLength; >+ if (bytesPerComponent >= pack) >+ paddedRowLength = numComponents * width; >+ else >+ paddedRowLength = Math.floor((rowSize + pack - 1) / pack) * pack / bytesPerComponent; >+ var size = width * numComponents + (height - 1) * paddedRowLength; >+ var buf = new (glTypeToTypedArrayType(gl, opt_type))(size); >+ for (var yy = 0; yy < height; ++yy) { >+ var off = yy * paddedRowLength; >+ for (var xx = 0; xx < width; ++xx) { >+ for (var jj = 0; jj < numComponents; ++jj) { >+ buf[off++] = color[jj]; >+ } >+ } >+ } >+ gl.bindTexture(gl.TEXTURE_2D, tex); >+ gl.texImage2D( >+ gl.TEXTURE_2D, opt_level, opt_internalFormat, width, height, 0, >+ opt_format, opt_type, buf); >+}; >+ >+/** >+ * Creates a texture and fills it with a solid color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} width The width of the texture to create. >+ * @param {number} height The height of the texture to create. >+ * @param {!Array.<number>} color The color to fill with. A 4 element array >+ * where each element is in the range 0 to 255. >+ * @return {!WebGLTexture} >+ */ >+var createColoredTexture = function(gl, width, height, color) { >+ var tex = gl.createTexture(); >+ fillTexture(gl, tex, width, height, color); >+ return tex; >+}; >+ >+var ubyteToFloat = function(c) { >+ return c / 255; >+}; >+ >+var ubyteColorToFloatColor = function(color) { >+ var floatColor = []; >+ for (var ii = 0; ii < color.length; ++ii) { >+ floatColor[ii] = ubyteToFloat(color[ii]); >+ } >+ return floatColor; >+}; >+ >+/** >+ * Sets the "u_color" uniform of the current program to color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} color 4 element array of 0-1 color >+ * components. >+ */ >+var setFloatDrawColor = function(gl, color) { >+ var program = gl.getParameter(gl.CURRENT_PROGRAM); >+ var colorLocation = gl.getUniformLocation(program, "u_color"); >+ gl.uniform4fv(colorLocation, color); >+}; >+ >+/** >+ * Sets the "u_color" uniform of the current program to color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} color 4 element array of 0-255 color >+ * components. >+ */ >+var setUByteDrawColor = function(gl, color) { >+ setFloatDrawColor(gl, ubyteColorToFloatColor(color)); >+}; >+ >+/** >+ * Draws a previously setup quad in the given color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} color The color to draw with. A 4 >+ * element array where each element is in the range 0 to >+ * 1. >+ */ >+var drawFloatColorQuad = function(gl, color) { >+ var program = gl.getParameter(gl.CURRENT_PROGRAM); >+ var colorLocation = gl.getUniformLocation(program, "u_color"); >+ gl.uniform4fv(colorLocation, color); >+ gl.drawArrays(gl.TRIANGLES, 0, 6); >+}; >+ >+ >+/** >+ * Draws a previously setup quad in the given color. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} color The color to draw with. A 4 >+ * element array where each element is in the range 0 to >+ * 255. >+ */ >+var drawUByteColorQuad = function(gl, color) { >+ drawFloatColorQuad(gl, ubyteColorToFloatColor(color)); >+}; >+ >+/** >+ * Draws a previously setupUnitQuad. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ */ >+var drawUnitQuad = function(gl) { >+ gl.drawArrays(gl.TRIANGLES, 0, 6); >+}; >+ >+var dummySetProgramAndDrawNothing = function(gl) { >+ if (!gl._wtuDummyProgram) { >+ gl._wtuDummyProgram = setupProgram(gl, [ >+ "void main() { gl_Position = vec4(0.0); }", >+ "void main() { gl_FragColor = vec4(0.0); }" >+ ], [], []); >+ } >+ gl.useProgram(gl._wtuDummyProgram); >+ gl.drawArrays(gl.TRIANGLES, 0, 3); >+}; >+ >+/** >+ * Clears then Draws a previously setupUnitQuad. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!Array.<number>} opt_color The color to fill clear with before >+ * drawing. A 4 element array where each element is in the range 0 to >+ * 255. Default [255, 255, 255, 255] >+ */ >+var clearAndDrawUnitQuad = function(gl, opt_color) { >+ opt_color = opt_color || [255, 255, 255, 255]; >+ gl.clearColor( >+ opt_color[0] / 255, >+ opt_color[1] / 255, >+ opt_color[2] / 255, >+ opt_color[3] / 255); >+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); >+ drawUnitQuad(gl); >+}; >+ >+/** >+ * Draws a quad previously setup with setupIndexedQuad. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} gridRes Resolution of grid. >+ */ >+var drawIndexedQuad = function(gl, gridRes) { >+ gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0); >+}; >+ >+/** >+ * Draws a previously setupIndexedQuad >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number} gridRes Resolution of grid. >+ * @param {!Array.<number>} opt_color The color to fill clear with before >+ * drawing. A 4 element array where each element is in the range 0 to >+ * 255. Default [255, 255, 255, 255] >+ */ >+var clearAndDrawIndexedQuad = function(gl, gridRes, opt_color) { >+ opt_color = opt_color || [255, 255, 255, 255]; >+ gl.clearColor( >+ opt_color[0] / 255, >+ opt_color[1] / 255, >+ opt_color[2] / 255, >+ opt_color[3] / 255); >+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); >+ drawIndexedQuad(gl, gridRes); >+}; >+ >+/** >+ * Clips a range to min, max >+ * (Eg. clipToRange(-5,7,0,20) would return {value:0,extent:2} >+ * @param {number} value start of range >+ * @param {number} extent extent of range >+ * @param {number} min min. >+ * @param {number} max max. >+ * @return {!{value:number,extent:number}} The clipped value. >+ */ >+var clipToRange = function(value, extent, min, max) { >+ if (value < min) { >+ extent -= min - value; >+ value = min; >+ } >+ var end = value + extent; >+ if (end > max) { >+ extent -= end - max; >+ } >+ if (extent < 0) { >+ value = max; >+ extent = 0; >+ } >+ return {value:value, extent: extent}; >+}; >+ >+/** >+ * Determines if the passed context is an instance of a WebGLRenderingContext >+ * or later variant (like WebGL2RenderingContext) >+ * @param {CanvasRenderingContext} ctx The context to check. >+ */ >+var isWebGLContext = function(ctx) { >+ if (ctx instanceof WebGLRenderingContext) >+ return true; >+ >+ if ('WebGL2RenderingContext' in window && ctx instanceof WebGL2RenderingContext) >+ return true; >+ >+ return false; >+}; >+ >+/** >+ * Creates a check rect is used by checkCanvasRects. >+ * @param {number} x left corner of region to check. >+ * @param {number} y bottom corner of region to check in case of checking from >+ * a GL context or top corner in case of checking from a 2D context. >+ * @param {number} width width of region to check. >+ * @param {number} height width of region to check. >+ * @param {!Array.<number>} color The color expected. A 4 element array where >+ * each element is in the range 0 to 255. >+ * @param {string} opt_msg Message to associate with success. Eg >+ * ("should be red"). >+ * @param {number} opt_errorRange Optional. Acceptable error in >+ * color checking. 0 by default. >+ */ >+var makeCheckRect = function(x, y, width, height, color, msg, errorRange) { >+ var rect = { >+ 'x': x, 'y': y, >+ 'width': width, 'height': height, >+ 'color': color, 'msg': msg, >+ 'errorRange': errorRange, >+ >+ 'checkRect': function (buf, l, b, w) { >+ for (var px = (x - l) ; px < (x + width - l) ; ++px) { >+ for (var py = (y - b) ; py < (y + height - b) ; ++py) { >+ var offset = (py * w + px) * 4; >+ for (var j = 0; j < color.length; ++j) { >+ if (Math.abs(buf[offset + j] - color[j]) > errorRange) { >+ testFailed(msg); >+ var was = buf[offset + 0].toString(); >+ for (j = 1; j < color.length; ++j) { >+ was += "," + buf[offset + j]; >+ } >+ debug('at (' + px + ', ' + py + >+ ') expected: ' + color + ' was ' + was); >+ return; >+ } >+ } >+ } >+ } >+ testPassed(msg); >+ } >+ } >+ return rect; >+}; >+ >+/** >+ * Checks that a portions of a canvas or the currently attached framebuffer is 1 color. >+ * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The >+ * WebGLRenderingContext or 2D context to use. >+ * @param {!Array.<checkRect>} array of rects to check for matching color. >+ */ >+var checkCanvasRects = function(gl, rects) { >+ if (rects.length > 0) { >+ var left = rects[0].x; >+ var right = rects[0].x + rects[1].width; >+ var bottom = rects[0].y; >+ var top = rects[0].y + rects[0].height; >+ for (var i = 1; i < rects.length; ++i) { >+ left = Math.min(left, rects[i].x); >+ right = Math.max(right, rects[i].x + rects[i].width); >+ bottom = Math.min(bottom, rects[i].y); >+ top = Math.max(top, rects[i].y + rects[i].height); >+ } >+ var width = right - left; >+ var height = top - bottom; >+ var buf = new Uint8Array(width * height * 4); >+ gl.readPixels(left, bottom, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); >+ for (var i = 0; i < rects.length; ++i) { >+ rects[i].checkRect(buf, left, bottom, width); >+ } >+ } >+}; >+ >+/** >+ * Checks that a portion of a canvas or the currently attached framebuffer is 1 color. >+ * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The >+ * WebGLRenderingContext or 2D context to use. >+ * @param {number} x left corner of region to check. >+ * @param {number} y bottom corner of region to check in case of checking from >+ * a GL context or top corner in case of checking from a 2D context. >+ * @param {number} width width of region to check. >+ * @param {number} height width of region to check. >+ * @param {!Array.<number>} color The color expected. A 4 element array where >+ * each element is in the range 0 to 255. >+ * @param {number} opt_errorRange Optional. Acceptable error in >+ * color checking. 0 by default. >+ * @param {!function()} sameFn Function to call if all pixels >+ * are the same as color. >+ * @param {!function()} differentFn Function to call if a pixel >+ * is different than color >+ * @param {!function()} logFn Function to call for logging. >+ * @param {TypedArray} opt_readBackBuf optional buffer to read back into. >+ * Typically passed to either reuse buffer, or support readbacks from >+ * floating-point framebuffers. >+ * @param {GLenum} opt_readBackType optional read back type, defaulting to >+ * gl.UNSIGNED_BYTE. Can be used to support readback from floating-point >+ * framebuffers. >+ */ >+var checkCanvasRectColor = function(gl, x, y, width, height, color, opt_errorRange, sameFn, differentFn, logFn, opt_readBackBuf, opt_readBackType) { >+ if (isWebGLContext(gl) && !gl.getParameter(gl.FRAMEBUFFER_BINDING)) { >+ // We're reading the backbuffer so clip. >+ var xr = clipToRange(x, width, 0, gl.canvas.width); >+ var yr = clipToRange(y, height, 0, gl.canvas.height); >+ if (!xr.extent || !yr.extent) { >+ logFn("checking rect: effective width or height is zero"); >+ sameFn(); >+ return; >+ } >+ x = xr.value; >+ y = yr.value; >+ width = xr.extent; >+ height = yr.extent; >+ } >+ var errorRange = opt_errorRange || 0; >+ if (!errorRange.length) { >+ errorRange = [errorRange, errorRange, errorRange, errorRange] >+ } >+ var buf; >+ if (isWebGLContext(gl)) { >+ buf = opt_readBackBuf ? opt_readBackBuf : new Uint8Array(width * height * 4); >+ var readBackType = opt_readBackType ? opt_readBackType : gl.UNSIGNED_BYTE; >+ gl.readPixels(x, y, width, height, gl.RGBA, readBackType, buf); >+ } else { >+ buf = gl.getImageData(x, y, width, height).data; >+ } >+ for (var i = 0; i < width * height; ++i) { >+ var offset = i * 4; >+ for (var j = 0; j < color.length; ++j) { >+ if (Math.abs(buf[offset + j] - color[j]) > errorRange[j]) { >+ var was = buf[offset + 0].toString(); >+ for (j = 1; j < color.length; ++j) { >+ was += "," + buf[offset + j]; >+ } >+ differentFn('at (' + (x + (i % width)) + ', ' + (y + Math.floor(i / width)) + >+ ') expected: ' + color + ' was ' + was); >+ return; >+ } >+ } >+ } >+ sameFn(); >+}; >+ >+/** >+ * Checks that a portion of a canvas or the currently attached framebuffer is 1 color. >+ * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The >+ * WebGLRenderingContext or 2D context to use. >+ * @param {number} x left corner of region to check. >+ * @param {number} y bottom corner of region to check in case of checking from >+ * a GL context or top corner in case of checking from a 2D context. >+ * @param {number} width width of region to check. >+ * @param {number} height width of region to check. >+ * @param {!Array.<number>} color The color expected. A 4 element array where >+ * each element is in the range 0 to 255. >+ * @param {string} opt_msg Message to associate with success or failure. Eg >+ * ("should be red"). >+ * @param {number} opt_errorRange Optional. Acceptable error in >+ * color checking. 0 by default. >+ * @param {TypedArray} opt_readBackBuf optional buffer to read back into. >+ * Typically passed to either reuse buffer, or support readbacks from >+ * floating-point framebuffers. >+ * @param {GLenum} opt_readBackType optional read back type, defaulting to >+ * gl.UNSIGNED_BYTE. Can be used to support readback from floating-point >+ * framebuffers. >+ */ >+var checkCanvasRect = function(gl, x, y, width, height, color, opt_msg, opt_errorRange, opt_readBackBuf, opt_readBackType) { >+ checkCanvasRectColor( >+ gl, x, y, width, height, color, opt_errorRange, >+ function() { >+ var msg = opt_msg; >+ if (msg === undefined) >+ msg = "should be " + color.toString(); >+ testPassed(msg); >+ }, >+ function(differentMsg) { >+ var msg = opt_msg; >+ if (msg === undefined) >+ msg = "should be " + color.toString(); >+ testFailed(msg + "\n" + differentMsg); >+ }, >+ debug, >+ opt_readBackBuf, >+ opt_readBackType); >+}; >+ >+/** >+ * Checks that an entire canvas or the currently attached framebuffer is 1 color. >+ * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The >+ * WebGLRenderingContext or 2D context to use. >+ * @param {!Array.<number>} color The color expected. A 4 element array where >+ * each element is in the range 0 to 255. >+ * @param {string} msg Message to associate with success. Eg ("should be red"). >+ * @param {number} errorRange Optional. Acceptable error in >+ * color checking. 0 by default. >+ */ >+var checkCanvas = function(gl, color, msg, errorRange) { >+ checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, color, msg, errorRange); >+}; >+ >+/** >+ * Checks a rectangular area both inside the area and outside >+ * the area. >+ * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The >+ * WebGLRenderingContext or 2D context to use. >+ * @param {number} x left corner of region to check. >+ * @param {number} y bottom corner of region to check in case of checking from >+ * a GL context or top corner in case of checking from a 2D context. >+ * @param {number} width width of region to check. >+ * @param {number} height width of region to check. >+ * @param {!Array.<number>} innerColor The color expected inside >+ * the area. A 4 element array where each element is in the >+ * range 0 to 255. >+ * @param {!Array.<number>} outerColor The color expected >+ * outside. A 4 element array where each element is in the >+ * range 0 to 255. >+ * @param {!number} opt_edgeSize: The number of pixels to skip >+ * around the edges of the area. Defaut 0. >+ * @param {!{width:number, height:number}} opt_outerDimensions >+ * The outer dimensions. Default the size of gl.canvas. >+ */ >+var checkAreaInAndOut = function(gl, x, y, width, height, innerColor, outerColor, opt_edgeSize, opt_outerDimensions) { >+ var outerDimensions = opt_outerDimensions || { width: gl.canvas.width, height: gl.canvas.height }; >+ var edgeSize = opt_edgeSize || 0; >+ checkCanvasRect(gl, x + edgeSize, y + edgeSize, width - edgeSize * 2, height - edgeSize * 2, innerColor); >+ checkCanvasRect(gl, 0, 0, x - edgeSize, outerDimensions.height, outerColor); >+ checkCanvasRect(gl, x + width + edgeSize, 0, outerDimensions.width - x - width - edgeSize, outerDimensions.height, outerColor); >+ checkCanvasRect(gl, 0, 0, outerDimensions.width, y - edgeSize, outerColor); >+ checkCanvasRect(gl, 0, y + height + edgeSize, outerDimensions.width, outerDimensions.height - y - height - edgeSize, outerColor); >+}; >+ >+/** >+ * Checks that an entire buffer matches the floating point values provided. >+ * (WebGL 2.0 only) >+ * @param {!WebGL2RenderingContext} gl The WebGL2RenderingContext to use. >+ * @param {number} target The buffer target to bind to. >+ * @param {!Array.<number>} expected The values expected. >+ * @param {string} opt_msg Optional. Message to associate with success. Eg ("should be red"). >+ * @param {number} opt_errorRange Optional. Acceptable error in value checking. 0.001 by default. >+ */ >+var checkFloatBuffer = function(gl, target, expected, opt_msg, opt_errorRange) { >+ if (opt_msg === undefined) >+ opt_msg = "buffer should match expected values"; >+ >+ if (opt_errorRange === undefined) >+ opt_errorRange = 0.001; >+ >+ var floatArray = new Float32Array(expected.length); >+ gl.getBufferSubData(target, 0, floatArray); >+ >+ for (var i = 0; i < expected.length; i++) { >+ if (Math.abs(floatArray[i] - expected[i]) > opt_errorRange) { >+ testFailed(opt_msg); >+ debug('at [' + i + '] expected: ' + expected[i] + ' was ' + floatArray[i]); >+ return; >+ } >+ } >+ testPassed(opt_msg); >+}; >+ >+/** >+ * Loads a texture, calls callback when finished. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} url URL of image to load >+ * @param {function(!Image): void} callback Function that gets called after >+ * image has loaded >+ * @return {!WebGLTexture} The created texture. >+ */ >+var loadTexture = function(gl, url, callback) { >+ var texture = gl.createTexture(); >+ gl.bindTexture(gl.TEXTURE_2D, texture); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); >+ var image = new Image(); >+ image.onload = function() { >+ gl.bindTexture(gl.TEXTURE_2D, texture); >+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); >+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); >+ callback(image); >+ }; >+ image.src = url; >+ return texture; >+}; >+ >+/** >+ * Checks whether the bound texture has expected dimensions. One corner pixel >+ * of the texture will be changed as a side effect. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!WebGLTexture} texture The texture to check. >+ * @param {number} width Expected width. >+ * @param {number} height Expected height. >+ * @param {GLenum} opt_format The texture's format. Defaults to RGBA. >+ * @param {GLenum} opt_type The texture's type. Defaults to UNSIGNED_BYTE. >+ */ >+var checkTextureSize = function(gl, width, height, opt_format, opt_type) { >+ opt_format = opt_format || gl.RGBA; >+ opt_type = opt_type || gl.UNSIGNED_BYTE; >+ >+ var numElements = getTypedArrayElementsPerPixel(gl, opt_format, opt_type); >+ var buf = new (glTypeToTypedArrayType(gl, opt_type))(numElements); >+ >+ var errors = 0; >+ gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height - 1, 1, 1, opt_format, opt_type, buf); >+ if (gl.getError() != gl.NO_ERROR) { >+ testFailed("Texture was smaller than the expected size " + width + "x" + height); >+ ++errors; >+ } >+ gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height, 1, 1, opt_format, opt_type, buf); >+ if (gl.getError() == gl.NO_ERROR) { >+ testFailed("Texture was taller than " + height); >+ ++errors; >+ } >+ gl.texSubImage2D(gl.TEXTURE_2D, 0, width, height - 1, 1, 1, opt_format, opt_type, buf); >+ if (gl.getError() == gl.NO_ERROR) { >+ testFailed("Texture was wider than " + width); >+ ++errors; >+ } >+ if (errors == 0) { >+ testPassed("Texture had the expected size " + width + "x" + height); >+ } >+}; >+ >+/** >+ * Makes a shallow copy of an object. >+ * @param {!Object} src Object to copy >+ * @return {!Object} The copy of src. >+ */ >+var shallowCopyObject = function(src) { >+ var dst = {}; >+ for (var attr in src) { >+ if (src.hasOwnProperty(attr)) { >+ dst[attr] = src[attr]; >+ } >+ } >+ return dst; >+}; >+ >+/** >+ * Checks if an attribute exists on an object case insensitive. >+ * @param {!Object} obj Object to check >+ * @param {string} attr Name of attribute to look for. >+ * @return {string?} The name of the attribute if it exists, >+ * undefined if not. >+ */ >+var hasAttributeCaseInsensitive = function(obj, attr) { >+ var lower = attr.toLowerCase(); >+ for (var key in obj) { >+ if (obj.hasOwnProperty(key) && key.toLowerCase() == lower) { >+ return key; >+ } >+ } >+}; >+ >+/** >+ * Returns a map of URL querystring options >+ * @return {Object?} Object containing all the values in the URL querystring >+ */ >+var getUrlOptions = (function() { >+ var _urlOptionsParsed = false; >+ var _urlOptions = {}; >+ return function() { >+ if (!_urlOptionsParsed) { >+ var s = window.location.href; >+ var q = s.indexOf("?"); >+ var e = s.indexOf("#"); >+ if (e < 0) { >+ e = s.length; >+ } >+ var query = s.substring(q + 1, e); >+ var pairs = query.split("&"); >+ for (var ii = 0; ii < pairs.length; ++ii) { >+ var keyValue = pairs[ii].split("="); >+ var key = keyValue[0]; >+ var value = decodeURIComponent(keyValue[1]); >+ _urlOptions[key] = value; >+ } >+ _urlOptionsParsed = true; >+ } >+ >+ return _urlOptions; >+ } >+})(); >+ >+var default3DContextVersion = 1; >+ >+/** >+ * Set the default context version for create3DContext. >+ * Initially the default version is 1. >+ * @param {number} Default version of WebGL contexts. >+ */ >+var setDefault3DContextVersion = function(version) { >+ default3DContextVersion = version; >+}; >+ >+/** >+ * Get the default contex version for create3DContext. >+ * First it looks at the URI option |webglVersion|. If it does not exist, >+ * then look at the global default3DContextVersion variable. >+ */ >+var getDefault3DContextVersion = function() { >+ return parseInt(getUrlOptions().webglVersion, 10) || default3DContextVersion; >+}; >+ >+/** >+ * Creates a webgl context. >+ * @param {!Canvas|string} opt_canvas The canvas tag to get >+ * context from. If one is not passed in one will be >+ * created. If it's a string it's assumed to be the id of a >+ * canvas. >+ * @param {Object} opt_attributes Context attributes. >+ * @param {!number} opt_version Version of WebGL context to create. >+ * The default version can be set by calling setDefault3DContextVersion. >+ * @return {!WebGLRenderingContext} The created context. >+ */ >+var create3DContext = function(opt_canvas, opt_attributes, opt_version) { >+ if (window.initTestingHarness) { >+ window.initTestingHarness(); >+ } >+ var attributes = shallowCopyObject(opt_attributes || {}); >+ if (!hasAttributeCaseInsensitive(attributes, "antialias")) { >+ attributes.antialias = false; >+ } >+ if (!opt_version) { >+ opt_version = parseInt(getUrlOptions().webglVersion, 10) || default3DContextVersion; >+ } >+ opt_canvas = opt_canvas || document.createElement("canvas"); >+ if (typeof opt_canvas == 'string') { >+ opt_canvas = document.getElementById(opt_canvas); >+ } >+ var context = null; >+ >+ var names; >+ switch (opt_version) { >+ case 2: >+ names = ["webgl2"]; break; >+ default: >+ names = ["webgl", "experimental-webgl"]; break; >+ } >+ >+ for (var i = 0; i < names.length; ++i) { >+ try { >+ context = opt_canvas.getContext(names[i], attributes); >+ } catch (e) { >+ } >+ if (context) { >+ break; >+ } >+ } >+ if (!context) { >+ testFailed("Unable to fetch WebGL rendering context for Canvas"); >+ } >+ return context; >+}; >+ >+/** >+ * Defines the exception type for a GL error. >+ * @constructor >+ * @param {string} message The error message. >+ * @param {number} error GL error code >+ */ >+function GLErrorException (message, error) { >+ this.message = message; >+ this.name = "GLErrorException"; >+ this.error = error; >+}; >+ >+/** >+ * Wraps a WebGL function with a function that throws an exception if there is >+ * an error. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} fname Name of function to wrap. >+ * @return {function()} The wrapped function. >+ */ >+var createGLErrorWrapper = function(context, fname) { >+ return function() { >+ var rv = context[fname].apply(context, arguments); >+ var err = context.getError(); >+ if (err != context.NO_ERROR) { >+ var msg = "GL error " + glEnumToString(context, err) + " in " + fname; >+ throw new GLErrorException(msg, err); >+ } >+ return rv; >+ }; >+}; >+ >+/** >+ * Creates a WebGL context where all functions are wrapped to throw an exception >+ * if there is an error. >+ * @param {!Canvas} canvas The HTML canvas to get a context from. >+ * @param {Object} opt_attributes Context attributes. >+ * @param {!number} opt_version Version of WebGL context to create >+ * @return {!Object} The wrapped context. >+ */ >+function create3DContextWithWrapperThatThrowsOnGLError(canvas, opt_attributes, opt_version) { >+ var context = create3DContext(canvas, opt_attributes, opt_version); >+ var wrap = {}; >+ for (var i in context) { >+ try { >+ if (typeof context[i] == 'function') { >+ wrap[i] = createGLErrorWrapper(context, i); >+ } else { >+ wrap[i] = context[i]; >+ } >+ } catch (e) { >+ error("createContextWrapperThatThrowsOnGLError: Error accessing " + i); >+ } >+ } >+ wrap.getError = function() { >+ return context.getError(); >+ }; >+ return wrap; >+}; >+ >+/** >+ * Tests that an evaluated expression generates a specific GL error. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors. >+ * @param {string} evalStr The string to evaluate. >+ */ >+var shouldGenerateGLError = function(gl, glErrors, evalStr, opt_msg) { >+ var exception; >+ try { >+ eval(evalStr); >+ } catch (e) { >+ exception = e; >+ } >+ if (exception) { >+ testFailed(evalStr + " threw exception " + exception); >+ return -1; >+ } else { >+ if (!opt_msg) { >+ opt_msg = "after evaluating: " + evalStr; >+ } >+ return glErrorShouldBe(gl, glErrors, opt_msg); >+ } >+}; >+ >+/** >+ * Tests that an evaluated expression does not generate a GL error. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} evalStr The string to evaluate. >+ */ >+var failIfGLError = function(gl, evalStr) { >+ var exception; >+ try { >+ eval(evalStr); >+ } catch (e) { >+ exception = e; >+ } >+ if (exception) { >+ testFailed(evalStr + " threw exception " + exception); >+ } else { >+ glErrorShouldBeImpl(gl, gl.NO_ERROR, false, "after evaluating: " + evalStr); >+ } >+}; >+ >+/** >+ * Tests that the first error GL returns is the specified error. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors. >+ * @param {string} opt_msg Optional additional message. >+ */ >+var glErrorShouldBe = function(gl, glErrors, opt_msg) { >+ return glErrorShouldBeImpl(gl, glErrors, true, opt_msg); >+}; >+ >+ >+ >+/** >+ * Tests that the first error GL returns is the specified error. Allows suppression of successes. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors. >+ * @param {boolean} reportSuccesses Whether to report successes as passes, or to silently pass. >+ * @param {string} opt_msg Optional additional message. >+ */ >+var glErrorShouldBeImpl = function(gl, glErrors, reportSuccesses, opt_msg) { >+ if (!glErrors.length) { >+ glErrors = [glErrors]; >+ } >+ opt_msg = opt_msg || ""; >+ var err = gl.getError(); >+ var ndx = glErrors.indexOf(err); >+ var errStrs = []; >+ for (var ii = 0; ii < glErrors.length; ++ii) { >+ errStrs.push(glEnumToString(gl, glErrors[ii])); >+ } >+ var expected = errStrs.join(" or "); >+ if (ndx < 0) { >+ var msg = "getError expected" + ((glErrors.length > 1) ? " one of: " : ": "); >+ testFailed(msg + expected + ". Was " + glEnumToString(gl, err) + " : " + opt_msg); >+ } else if (reportSuccesses) { >+ var msg = "getError was " + ((glErrors.length > 1) ? "one of: " : "expected value: "); >+ testPassed(msg + expected + " : " + opt_msg); >+ } >+ return err; >+}; >+ >+/** >+ * Links a WebGL program, throws if there are errors. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!WebGLProgram} program The WebGLProgram to link. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ */ >+var linkProgram = function(gl, program, opt_errorCallback) { >+ var errFn = opt_errorCallback || testFailed; >+ // Link the program >+ gl.linkProgram(program); >+ >+ // Check the link status >+ var linked = gl.getProgramParameter(program, gl.LINK_STATUS); >+ if (!linked) { >+ // something went wrong with the link >+ var error = gl.getProgramInfoLog (program); >+ >+ errFn("Error in program linking:" + error); >+ >+ gl.deleteProgram(program); >+ } >+}; >+ >+/** >+ * Loads text from an external file. This function is asynchronous. >+ * @param {string} url The url of the external file. >+ * @param {!function(bool, string): void} callback that is sent a bool for >+ * success and the string. >+ */ >+var loadTextFileAsync = function(url, callback) { >+ log ("loading: " + url); >+ var error = 'loadTextFileAsync failed to load url "' + url + '"'; >+ var request; >+ if (window.XMLHttpRequest) { >+ request = new XMLHttpRequest(); >+ if (request.overrideMimeType) { >+ request.overrideMimeType('text/plain'); >+ } >+ } else { >+ throw 'XMLHttpRequest is disabled'; >+ } >+ try { >+ request.open('GET', url, true); >+ request.onreadystatechange = function() { >+ if (request.readyState == 4) { >+ var text = ''; >+ // HTTP reports success with a 200 status. The file protocol reports >+ // success with zero. HTTP does not use zero as a status code (they >+ // start at 100). >+ // https://developer.mozilla.org/En/Using_XMLHttpRequest >+ var success = request.status == 200 || request.status == 0; >+ if (success) { >+ text = request.responseText; >+ log("completed load request: " + url); >+ } else { >+ log("loading " + url + " resulted in unexpected status: " + request.status + " " + request.statusText); >+ } >+ callback(success, text); >+ } >+ }; >+ request.onerror = function(errorEvent) { >+ log("error occurred loading " + url); >+ callback(false, ''); >+ }; >+ request.send(null); >+ } catch (err) { >+ log("failed to load: " + url + " with exception " + err.message); >+ callback(false, ''); >+ } >+}; >+ >+/** >+ * Recursively loads a file as a list. Each line is parsed for a relative >+ * path. If the file ends in .txt the contents of that file is inserted in >+ * the list. >+ * >+ * @param {string} url The url of the external file. >+ * @param {!function(bool, Array<string>): void} callback that is sent a bool >+ * for success and the array of strings. >+ */ >+var getFileListAsync = function(url, callback) { >+ var files = []; >+ >+ var getFileListImpl = function(url, callback) { >+ var files = []; >+ if (url.substr(url.length - 4) == '.txt') { >+ loadTextFileAsync(url, function() { >+ return function(success, text) { >+ if (!success) { >+ callback(false, ''); >+ return; >+ } >+ var lines = text.split('\n'); >+ var prefix = ''; >+ var lastSlash = url.lastIndexOf('/'); >+ if (lastSlash >= 0) { >+ prefix = url.substr(0, lastSlash + 1); >+ } >+ var fail = false; >+ var count = 1; >+ var index = 0; >+ for (var ii = 0; ii < lines.length; ++ii) { >+ var str = lines[ii].replace(/^\s\s*/, '').replace(/\s\s*$/, ''); >+ if (str.length > 4 && >+ str[0] != '#' && >+ str[0] != ";" && >+ str.substr(0, 2) != "//") { >+ var names = str.split(/ +/); >+ var new_url = prefix + str; >+ if (names.length == 1) { >+ new_url = prefix + str; >+ ++count; >+ getFileListImpl(new_url, function(index) { >+ return function(success, new_files) { >+ log("got files: " + new_files.length); >+ if (success) { >+ files[index] = new_files; >+ } >+ finish(success); >+ }; >+ }(index++)); >+ } else { >+ var s = ""; >+ var p = ""; >+ for (var jj = 0; jj < names.length; ++jj) { >+ s += p + prefix + names[jj]; >+ p = " "; >+ } >+ files[index++] = s; >+ } >+ } >+ } >+ finish(true); >+ >+ function finish(success) { >+ if (!success) { >+ fail = true; >+ } >+ --count; >+ log("count: " + count); >+ if (!count) { >+ callback(!fail, files); >+ } >+ } >+ } >+ }()); >+ >+ } else { >+ files.push(url); >+ callback(true, files); >+ } >+ }; >+ >+ getFileListImpl(url, function(success, files) { >+ // flatten >+ var flat = []; >+ flatten(files); >+ function flatten(files) { >+ for (var ii = 0; ii < files.length; ++ii) { >+ var value = files[ii]; >+ if (typeof(value) == "string") { >+ flat.push(value); >+ } else { >+ flatten(value); >+ } >+ } >+ } >+ callback(success, flat); >+ }); >+}; >+ >+/** >+ * Gets a file from a file/URL. >+ * @param {string} file the URL of the file to get. >+ * @return {string} The contents of the file. >+ */ >+var readFile = function(file) { >+ var xhr = new XMLHttpRequest(); >+ xhr.open("GET", file, false); >+ xhr.overrideMimeType("text/plain"); >+ xhr.send(); >+ return xhr.responseText.replace(/\r/g, ""); >+}; >+ >+var readFileList = function(url) { >+ var files = []; >+ if (url.substr(url.length - 4) == '.txt') { >+ var lines = readFile(url).split('\n'); >+ var prefix = ''; >+ var lastSlash = url.lastIndexOf('/'); >+ if (lastSlash >= 0) { >+ prefix = url.substr(0, lastSlash + 1); >+ } >+ for (var ii = 0; ii < lines.length; ++ii) { >+ var str = lines[ii].replace(/^\s\s*/, '').replace(/\s\s*$/, ''); >+ if (str.length > 4 && >+ str[0] != '#' && >+ str[0] != ";" && >+ str.substr(0, 2) != "//") { >+ var names = str.split(/ +/); >+ if (names.length == 1) { >+ var new_url = prefix + str; >+ files = files.concat(readFileList(new_url)); >+ } else { >+ var s = ""; >+ var p = ""; >+ for (var jj = 0; jj < names.length; ++jj) { >+ s += p + prefix + names[jj]; >+ p = " "; >+ } >+ files.push(s); >+ } >+ } >+ } >+ } else { >+ files.push(url); >+ } >+ return files; >+}; >+ >+/** >+ * Loads a shader. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} shaderSource The shader source. >+ * @param {number} shaderType The type of shader. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ * @param {string} opt_shaderLabel Label that identifies the shader source in >+ * the log. >+ * @param {string} opt_url URL from where the shader source was loaded from. >+ * If opt_logShaders is set, then a link to the source file will also be >+ * added. >+ * @param {boolean} Skip compilation status check. Default = false. >+ * @return {!WebGLShader} The created shader. >+ */ >+var loadShader = function( >+ gl, shaderSource, shaderType, opt_errorCallback, opt_logShaders, >+ opt_shaderLabel, opt_url, opt_skipCompileStatus) { >+ var errFn = opt_errorCallback || error; >+ // Create the shader object >+ var shader = gl.createShader(shaderType); >+ if (shader == null) { >+ errFn("*** Error: unable to create shader '"+shaderSource+"'"); >+ return null; >+ } >+ >+ // Load the shader source >+ gl.shaderSource(shader, shaderSource); >+ >+ // Compile the shader >+ gl.compileShader(shader); >+ >+ if (opt_logShaders) { >+ var label = shaderType == gl.VERTEX_SHADER ? 'vertex shader' : 'fragment_shader'; >+ if (opt_shaderLabel) { >+ label = opt_shaderLabel + ' ' + label; >+ } >+ addShaderSources( >+ gl, document.getElementById('console'), label, shader, shaderSource, opt_url); >+ } >+ >+ // Check the compile status >+ if (!opt_skipCompileStatus) { >+ var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); >+ if (!compiled) { >+ // Something went wrong during compilation; get the error >+ lastError = gl.getShaderInfoLog(shader); >+ errFn("*** Error compiling " + glEnumToString(gl, shaderType) + " '" + shader + "':" + lastError); >+ gl.deleteShader(shader); >+ return null; >+ } >+ } >+ >+ return shader; >+} >+ >+/** >+ * Loads a shader from a URL. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {file} file The URL of the shader source. >+ * @param {number} type The type of shader. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ * @param {boolean} Skip compilation status check. Default = false. >+ * @return {!WebGLShader} The created shader. >+ */ >+var loadShaderFromFile = function( >+ gl, file, type, opt_errorCallback, opt_logShaders, opt_skipCompileStatus) { >+ var shaderSource = readFile(file); >+ return loadShader(gl, shaderSource, type, opt_errorCallback, >+ opt_logShaders, undefined, file, opt_skipCompileStatus); >+}; >+ >+var loadShaderFromFileAsync = function( >+ gl, file, type, opt_errorCallback, opt_logShaders, opt_skipCompileStatus, callback) { >+ loadTextFileAsync(file, function(gl, type, opt_errorCallback, opt_logShaders, file, opt_skipCompileStatus){ >+ return function(success, shaderSource) { >+ if (success) { >+ var shader = loadShader(gl, shaderSource, type, opt_errorCallback, >+ opt_logShaders, undefined, file, opt_skipCompileStatus); >+ callback(true, shader); >+ } else { >+ callback(false, null); >+ } >+ } >+ }(gl, type, opt_errorCallback, opt_logShaders, file, opt_skipCompileStatus)); >+}; >+ >+/** >+ * Gets the content of script. >+ * @param {string} scriptId The id of the script tag. >+ * @return {string} The content of the script. >+ */ >+var getScript = function(scriptId) { >+ var shaderScript = document.getElementById(scriptId); >+ if (!shaderScript) { >+ throw("*** Error: unknown script element " + scriptId); >+ } >+ return shaderScript.text; >+}; >+ >+/** >+ * Loads a shader from a script tag. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} scriptId The id of the script tag. >+ * @param {number} opt_shaderType The type of shader. If not passed in it will >+ * be derived from the type of the script tag. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ * @param {boolean} Skip compilation status check. Default = false. >+ * @return {!WebGLShader} The created shader. >+ */ >+var loadShaderFromScript = function( >+ gl, scriptId, opt_shaderType, opt_errorCallback, opt_logShaders, opt_skipCompileStatus) { >+ var shaderSource = ""; >+ var shaderScript = document.getElementById(scriptId); >+ if (!shaderScript) { >+ throw("*** Error: unknown script element " + scriptId); >+ } >+ shaderSource = shaderScript.text; >+ >+ if (!opt_shaderType) { >+ if (shaderScript.type == "x-shader/x-vertex") { >+ opt_shaderType = gl.VERTEX_SHADER; >+ } else if (shaderScript.type == "x-shader/x-fragment") { >+ opt_shaderType = gl.FRAGMENT_SHADER; >+ } else { >+ throw("*** Error: unknown shader type"); >+ return null; >+ } >+ } >+ >+ return loadShader(gl, shaderSource, opt_shaderType, opt_errorCallback, >+ opt_logShaders, undefined, undefined, opt_skipCompileStatus); >+}; >+ >+var loadStandardProgram = function(gl) { >+ var program = gl.createProgram(); >+ gl.attachShader(program, loadStandardVertexShader(gl)); >+ gl.attachShader(program, loadStandardFragmentShader(gl)); >+ gl.bindAttribLocation(program, 0, "a_vertex"); >+ gl.bindAttribLocation(program, 1, "a_normal"); >+ linkProgram(gl, program); >+ return program; >+}; >+ >+var loadStandardProgramAsync = function(gl, callback) { >+ loadStandardVertexShaderAsync(gl, function(gl) { >+ return function(success, vs) { >+ if (success) { >+ loadStandardFragmentShaderAsync(gl, function(vs) { >+ return function(success, fs) { >+ if (success) { >+ var program = gl.createProgram(); >+ gl.attachShader(program, vs); >+ gl.attachShader(program, fs); >+ gl.bindAttribLocation(program, 0, "a_vertex"); >+ gl.bindAttribLocation(program, 1, "a_normal"); >+ linkProgram(gl, program); >+ callback(true, program); >+ } else { >+ callback(false, null); >+ } >+ }; >+ }(vs)); >+ } else { >+ callback(false, null); >+ } >+ }; >+ }(gl)); >+}; >+ >+/** >+ * Loads shaders from files, creates a program, attaches the shaders and links. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} vertexShaderPath The URL of the vertex shader. >+ * @param {string} fragmentShaderPath The URL of the fragment shader. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @return {!WebGLProgram} The created program. >+ */ >+var loadProgramFromFile = function( >+ gl, vertexShaderPath, fragmentShaderPath, opt_errorCallback) { >+ var program = gl.createProgram(); >+ var vs = loadShaderFromFile( >+ gl, vertexShaderPath, gl.VERTEX_SHADER, opt_errorCallback); >+ var fs = loadShaderFromFile( >+ gl, fragmentShaderPath, gl.FRAGMENT_SHADER, opt_errorCallback); >+ if (vs && fs) { >+ gl.attachShader(program, vs); >+ gl.attachShader(program, fs); >+ linkProgram(gl, program, opt_errorCallback); >+ } >+ if (vs) { >+ gl.deleteShader(vs); >+ } >+ if (fs) { >+ gl.deleteShader(fs); >+ } >+ return program; >+}; >+ >+/** >+ * Loads shaders from script tags, creates a program, attaches the shaders and >+ * links. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} vertexScriptId The id of the script tag that contains the >+ * vertex shader. >+ * @param {string} fragmentScriptId The id of the script tag that contains the >+ * fragment shader. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @return {!WebGLProgram} The created program. >+ */ >+var loadProgramFromScript = function loadProgramFromScript( >+ gl, vertexScriptId, fragmentScriptId, opt_errorCallback) { >+ var program = gl.createProgram(); >+ gl.attachShader( >+ program, >+ loadShaderFromScript( >+ gl, vertexScriptId, gl.VERTEX_SHADER, opt_errorCallback)); >+ gl.attachShader( >+ program, >+ loadShaderFromScript( >+ gl, fragmentScriptId, gl.FRAGMENT_SHADER, opt_errorCallback)); >+ linkProgram(gl, program, opt_errorCallback); >+ return program; >+}; >+ >+/** >+ * Loads shaders from source, creates a program, attaches the shaders and >+ * links. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!WebGLShader} vertexShader The vertex shader. >+ * @param {!WebGLShader} fragmentShader The fragment shader. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @return {!WebGLProgram} The created program. >+ */ >+var createProgram = function(gl, vertexShader, fragmentShader, opt_errorCallback) { >+ var program = gl.createProgram(); >+ gl.attachShader(program, vertexShader); >+ gl.attachShader(program, fragmentShader); >+ linkProgram(gl, program, opt_errorCallback); >+ return program; >+}; >+ >+/** >+ * Loads shaders from source, creates a program, attaches the shaders and >+ * links. >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} vertexShader The vertex shader source. >+ * @param {string} fragmentShader The fragment shader source. >+ * @param {function(string): void} opt_errorCallback callback for errors. >+ * @param {boolean} opt_logShaders Whether to log shader source. >+ * @return {!WebGLProgram} The created program. >+ */ >+var loadProgram = function( >+ gl, vertexShader, fragmentShader, opt_errorCallback, opt_logShaders) { >+ var program; >+ var vs = loadShader( >+ gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback, opt_logShaders); >+ var fs = loadShader( >+ gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback, opt_logShaders); >+ if (vs && fs) { >+ program = createProgram(gl, vs, fs, opt_errorCallback) >+ } >+ if (vs) { >+ gl.deleteShader(vs); >+ } >+ if (fs) { >+ gl.deleteShader(fs); >+ } >+ return program; >+}; >+ >+/** >+ * Loads shaders from source, creates a program, attaches the shaders and >+ * links but expects error. >+ * >+ * GLSL 1.0.17 10.27 effectively says that compileShader can >+ * always succeed as long as linkProgram fails so we can't >+ * rely on compileShader failing. This function expects >+ * one of the shader to fail OR linking to fail. >+ * >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} vertexShaderScriptId The vertex shader. >+ * @param {string} fragmentShaderScriptId The fragment shader. >+ * @return {WebGLProgram} The created program. >+ */ >+var loadProgramFromScriptExpectError = function( >+ gl, vertexShaderScriptId, fragmentShaderScriptId) { >+ var vertexShader = loadShaderFromScript(gl, vertexShaderScriptId); >+ if (!vertexShader) { >+ return null; >+ } >+ var fragmentShader = loadShaderFromScript(gl, fragmentShaderScriptId); >+ if (!fragmentShader) { >+ return null; >+ } >+ var linkSuccess = true; >+ var program = gl.createProgram(); >+ gl.attachShader(program, vertexShader); >+ gl.attachShader(program, fragmentShader); >+ linkSuccess = true; >+ linkProgram(gl, program, function() { >+ linkSuccess = false; >+ }); >+ return linkSuccess ? program : null; >+}; >+ >+ >+var getActiveMap = function(gl, program, typeInfo) { >+ var numVariables = gl.getProgramParameter(program, gl[typeInfo.param]); >+ var variables = {}; >+ for (var ii = 0; ii < numVariables; ++ii) { >+ var info = gl[typeInfo.activeFn](program, ii); >+ variables[info.name] = { >+ name: info.name, >+ size: info.size, >+ type: info.type, >+ location: gl[typeInfo.locFn](program, info.name) >+ }; >+ } >+ return variables; >+}; >+ >+/** >+ * Returns a map of attrib names to info about those >+ * attribs. >+ * >+ * eg: >+ * { "attrib1Name": >+ * { >+ * name: "attrib1Name", >+ * size: 1, >+ * type: gl.FLOAT_MAT2, >+ * location: 0 >+ * }, >+ * "attrib2Name[0]": >+ * { >+ * name: "attrib2Name[0]", >+ * size: 4, >+ * type: gl.FLOAT, >+ * location: 1 >+ * }, >+ * } >+ * >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {WebGLProgram} The program to query for attribs. >+ * @return the map. >+ */ >+var getAttribMap = function(gl, program) { >+ return getActiveMap(gl, program, { >+ param: "ACTIVE_ATTRIBUTES", >+ activeFn: "getActiveAttrib", >+ locFn: "getAttribLocation" >+ }); >+}; >+ >+/** >+ * Returns a map of uniform names to info about those uniforms. >+ * >+ * eg: >+ * { "uniform1Name": >+ * { >+ * name: "uniform1Name", >+ * size: 1, >+ * type: gl.FLOAT_MAT2, >+ * location: WebGLUniformLocation >+ * }, >+ * "uniform2Name[0]": >+ * { >+ * name: "uniform2Name[0]", >+ * size: 4, >+ * type: gl.FLOAT, >+ * location: WebGLUniformLocation >+ * }, >+ * } >+ * >+ * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {WebGLProgram} The program to query for uniforms. >+ * @return the map. >+ */ >+var getUniformMap = function(gl, program) { >+ return getActiveMap(gl, program, { >+ param: "ACTIVE_UNIFORMS", >+ activeFn: "getActiveUniform", >+ locFn: "getUniformLocation" >+ }); >+}; >+ >+var basePath; >+var getResourcePath = function() { >+ if (!basePath) { >+ var expectedBase = "js/webgl-test-utils.js"; >+ var scripts = document.getElementsByTagName('script'); >+ for (var script, i = 0; script = scripts[i]; i++) { >+ var src = script.src; >+ var l = src.length; >+ if (src.substr(l - expectedBase.length) == expectedBase) { >+ basePath = src.substr(0, l - expectedBase.length); >+ } >+ } >+ } >+ return basePath + "resources/"; >+}; >+ >+var loadStandardVertexShader = function(gl) { >+ return loadShaderFromFile( >+ gl, getResourcePath() + "vertexShader.vert", gl.VERTEX_SHADER); >+}; >+var loadStandardVertexShaderAsync = function(gl, callback) { >+ loadShaderFromFileAsync(gl, getResourcePath() + "vertexShader.vert", gl.VERTEX_SHADER, undefined, undefined, undefined, callback); >+}; >+ >+var loadStandardFragmentShader = function(gl) { >+ return loadShaderFromFile( >+ gl, getResourcePath() + "fragmentShader.frag", gl.FRAGMENT_SHADER); >+}; >+var loadStandardFragmentShaderAsync = function(gl, callback) { >+ loadShaderFromFileAsync(gl, getResourcePath() + "fragmentShader.frag", gl.FRAGMENT_SHADER, undefined, undefined, undefined, callback); >+}; >+ >+var loadUniformBlockProgram = function(gl) { >+ var program = gl.createProgram(); >+ gl.attachShader(program, loadUniformBlockVertexShader(gl)); >+ gl.attachShader(program, loadUniformBlockFragmentShader(gl)); >+ gl.bindAttribLocation(program, 0, "a_vertex"); >+ gl.bindAttribLocation(program, 1, "a_normal"); >+ linkProgram(gl, program); >+ return program; >+}; >+ >+var loadUniformBlockVertexShader = function(gl) { >+ return loadShaderFromFile( >+ gl, getResourcePath() + "uniformBlockShader.vert", gl.VERTEX_SHADER); >+}; >+ >+var loadUniformBlockFragmentShader = function(gl) { >+ return loadShaderFromFile( >+ gl, getResourcePath() + "uniformBlockShader.frag", gl.FRAGMENT_SHADER); >+}; >+ >+/** >+ * Loads an image asynchronously. >+ * @param {string} url URL of image to load. >+ * @param {!function(!Element): void} callback Function to call >+ * with loaded image. >+ */ >+var loadImageAsync = function(url, callback) { >+ var img = document.createElement('img'); >+ img.onload = function() { >+ callback(img); >+ }; >+ img.src = url; >+}; >+ >+/** >+ * Loads an array of images. >+ * @param {!Array.<string>} urls URLs of images to load. >+ * @param {!function(!{string, img}): void} callback Callback >+ * that gets passed map of urls to img tags. >+ */ >+var loadImagesAsync = function(urls, callback) { >+ var count = 1; >+ var images = { }; >+ function countDown() { >+ --count; >+ if (count == 0) { >+ log("loadImagesAsync: all images loaded"); >+ callback(images); >+ } >+ } >+ function imageLoaded(url) { >+ return function(img) { >+ images[url] = img; >+ log("loadImagesAsync: loaded " + url); >+ countDown(); >+ } >+ } >+ for (var ii = 0; ii < urls.length; ++ii) { >+ ++count; >+ loadImageAsync(urls[ii], imageLoaded(urls[ii])); >+ } >+ countDown(); >+}; >+ >+/** >+ * Returns a map of key=value values from url. >+ * @return {!Object.<string, number>} map of keys to values. >+ */ >+var getUrlArguments = function() { >+ var args = {}; >+ try { >+ var s = window.location.href; >+ var q = s.indexOf("?"); >+ var e = s.indexOf("#"); >+ if (e < 0) { >+ e = s.length; >+ } >+ var query = s.substring(q + 1, e); >+ var pairs = query.split("&"); >+ for (var ii = 0; ii < pairs.length; ++ii) { >+ var keyValue = pairs[ii].split("="); >+ var key = keyValue[0]; >+ var value = decodeURIComponent(keyValue[1]); >+ args[key] = value; >+ } >+ } catch (e) { >+ throw "could not parse url"; >+ } >+ return args; >+}; >+ >+/** >+ * Makes an image from a src. >+ * @param {string} src Image source URL. >+ * @param {function()} onload Callback to call when the image has finised loading. >+ * @param {function()} onerror Callback to call when an error occurs. >+ * @return {!Image} The created image. >+ */ >+var makeImage = function(src, onload, onerror) { >+ var img = document.createElement('img'); >+ if (onload) { >+ img.onload = onload; >+ } >+ if (onerror) { >+ img.onerror = onerror; >+ } else { >+ img.onerror = function() { >+ log("WARNING: creating image failed; src: " + this.src); >+ }; >+ } >+ if (src) { >+ img.src = src; >+ } >+ return img; >+} >+ >+/** >+ * Makes an image element from a canvas. >+ * @param {!HTMLCanvas} canvas Canvas to make image from. >+ * @param {function()} onload Callback to call when the image has finised loading. >+ * @param {string} imageFormat Image format to be passed to toDataUrl(). >+ * @return {!Image} The created image. >+ */ >+var makeImageFromCanvas = function(canvas, onload, imageFormat) { >+ return makeImage(canvas.toDataURL(imageFormat), onload); >+}; >+ >+/** >+ * Makes a video element from a src. >+ * @param {string} src Video source URL. >+ * @param {function()} onerror Callback to call when an error occurs. >+ * @return {!Video} The created video. >+ */ >+var makeVideo = function(src, onerror) { >+ var vid = document.createElement('video'); >+ if (onerror) { >+ vid.onerror = onerror; >+ } else { >+ vid.onerror = function() { >+ log("WARNING: creating video failed; src: " + this.src); >+ }; >+ } >+ if (src) { >+ vid.src = src; >+ } >+ return vid; >+} >+ >+/** >+ * Inserts an image with a caption into 'element'. >+ * @param {!HTMLElement} element Element to append image to. >+ * @param {string} caption caption to associate with image. >+ * @param {!Image} img image to insert. >+ */ >+var insertImage = function(element, caption, img) { >+ var div = document.createElement("div"); >+ var label = document.createElement("div"); >+ label.appendChild(document.createTextNode(caption)); >+ div.appendChild(label); >+ div.appendChild(img); >+ element.appendChild(div); >+}; >+ >+/** >+ * Inserts a 'label' that when clicked expands to the pre formatted text >+ * supplied by 'source'. >+ * @param {!HTMLElement} element element to append label to. >+ * @param {string} label label for anchor. >+ * @param {string} source preformatted text to expand to. >+ * @param {string} opt_url URL of source. If provided a link to the source file >+ * will also be added. >+ */ >+var addShaderSource = function(element, label, source, opt_url) { >+ var div = document.createElement("div"); >+ var s = document.createElement("pre"); >+ s.className = "shader-source"; >+ s.style.display = "none"; >+ var ol = document.createElement("ol"); >+ //s.appendChild(document.createTextNode(source)); >+ var lines = source.split("\n"); >+ for (var ii = 0; ii < lines.length; ++ii) { >+ var line = lines[ii]; >+ var li = document.createElement("li"); >+ li.appendChild(document.createTextNode(line)); >+ ol.appendChild(li); >+ } >+ s.appendChild(ol); >+ var l = document.createElement("a"); >+ l.href = "show-shader-source"; >+ l.appendChild(document.createTextNode(label)); >+ l.addEventListener('click', function(event) { >+ if (event.preventDefault) { >+ event.preventDefault(); >+ } >+ s.style.display = (s.style.display == 'none') ? 'block' : 'none'; >+ return false; >+ }, false); >+ div.appendChild(l); >+ if (opt_url) { >+ var u = document.createElement("a"); >+ u.href = opt_url; >+ div.appendChild(document.createTextNode(" ")); >+ u.appendChild(document.createTextNode("(" + opt_url + ")")); >+ div.appendChild(u); >+ } >+ div.appendChild(s); >+ element.appendChild(div); >+}; >+ >+/** >+ * Inserts labels that when clicked expand to show the original source of the >+ * shader and also translated source of the shader, if that is available. >+ * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {!HTMLElement} element element to append label to. >+ * @param {string} label label for anchor. >+ * @param {WebGLShader} shader Shader to show the sources for. >+ * @param {string} shaderSource Original shader source. >+ * @param {string} opt_url URL of source. If provided a link to the source file >+ * will also be added. >+ */ >+var addShaderSources = function( >+ gl, element, label, shader, shaderSource, opt_url) { >+ addShaderSource(element, label, shaderSource, opt_url); >+ >+ var debugShaders = gl.getExtension('WEBGL_debug_shaders'); >+ if (debugShaders && shader) { >+ var translatedSource = debugShaders.getTranslatedShaderSource(shader); >+ if (translatedSource != '') { >+ addShaderSource(element, label + ' translated for driver', translatedSource); >+ } >+ } >+}; >+ >+/** >+ * Sends shader information to the server to be dumped into text files >+ * when tests are run from within the test-runner harness. >+ * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. >+ * @param {string} url URL of current. >+ * @param {string} passMsg Test description. >+ * @param {object} vInfo Object containing vertex shader information. >+ * @param {object} fInfo Object containing fragment shader information. >+ */ >+var dumpShadersInfo = function(gl, url, passMsg, vInfo, fInfo) { >+ var shaderInfo = {}; >+ shaderInfo.url = url; >+ shaderInfo.testDescription = passMsg; >+ shaderInfo.vLabel = vInfo.label; >+ shaderInfo.vShouldCompile = vInfo.shaderSuccess; >+ shaderInfo.vSource = vInfo.source; >+ shaderInfo.fLabel = fInfo.label; >+ shaderInfo.fShouldCompile = fInfo.shaderSuccess; >+ shaderInfo.fSource = fInfo.source; >+ shaderInfo.vTranslatedSource = null; >+ shaderInfo.fTranslatedSource = null; >+ var debugShaders = gl.getExtension('WEBGL_debug_shaders'); >+ if (debugShaders) { >+ if (vInfo.shader) >+ shaderInfo.vTranslatedSource = debugShaders.getTranslatedShaderSource(vInfo.shader); >+ if (fInfo.shader) >+ shaderInfo.fTranslatedSource = debugShaders.getTranslatedShaderSource(fInfo.shader); >+ } >+ >+ var dumpShaderInfoRequest = new XMLHttpRequest(); >+ dumpShaderInfoRequest.open('POST', "/dumpShaderInfo", true); >+ dumpShaderInfoRequest.setRequestHeader("Content-Type", "text/plain"); >+ dumpShaderInfoRequest.send(JSON.stringify(shaderInfo)); >+}; >+ >+// Add your prefix here. >+var browserPrefixes = [ >+ "", >+ "MOZ_", >+ "OP_", >+ "WEBKIT_" >+]; >+ >+/** >+ * Given an extension name like WEBGL_compressed_texture_s3tc >+ * returns the name of the supported version extension, like >+ * WEBKIT_WEBGL_compressed_teture_s3tc >+ * @param {string} name Name of extension to look for. >+ * @return {string} name of extension found or undefined if not >+ * found. >+ */ >+var getSupportedExtensionWithKnownPrefixes = function(gl, name) { >+ var supported = gl.getSupportedExtensions(); >+ for (var ii = 0; ii < browserPrefixes.length; ++ii) { >+ var prefixedName = browserPrefixes[ii] + name; >+ if (supported.indexOf(prefixedName) >= 0) { >+ return prefixedName; >+ } >+ } >+}; >+ >+/** >+ * Given an extension name like WEBGL_compressed_texture_s3tc >+ * returns the supported version extension, like >+ * WEBKIT_WEBGL_compressed_teture_s3tc >+ * @param {string} name Name of extension to look for. >+ * @return {WebGLExtension} The extension or undefined if not >+ * found. >+ */ >+var getExtensionWithKnownPrefixes = function(gl, name) { >+ for (var ii = 0; ii < browserPrefixes.length; ++ii) { >+ var prefixedName = browserPrefixes[ii] + name; >+ var ext = gl.getExtension(prefixedName); >+ if (ext) { >+ return ext; >+ } >+ } >+}; >+ >+/** >+ * Returns possible prefixed versions of an extension's name. >+ * @param {string} name Name of extension. May already include a prefix. >+ * @return {Array.<string>} Variations of the extension name with known >+ * browser prefixes. >+ */ >+var getExtensionPrefixedNames = function(name) { >+ var unprefix = function(name) { >+ for (var ii = 0; ii < browserPrefixes.length; ++ii) { >+ if (browserPrefixes[ii].length > 0 && >+ name.substring(0, browserPrefixes[ii].length).toLowerCase() === >+ browserPrefixes[ii].toLowerCase()) { >+ return name.substring(browserPrefixes[ii].length); >+ } >+ } >+ return name; >+ } >+ >+ var unprefixed = unprefix(name); >+ >+ var variations = []; >+ for (var ii = 0; ii < browserPrefixes.length; ++ii) { >+ variations.push(browserPrefixes[ii] + unprefixed); >+ } >+ >+ return variations; >+}; >+ >+var replaceRE = /\$\((\w+)\)/g; >+ >+/** >+ * Replaces strings with property values. >+ * Given a string like "hello $(first) $(last)" and an object >+ * like {first:"John", last:"Smith"} will return >+ * "hello John Smith". >+ * @param {string} str String to do replacements in. >+ * @param {...} 1 or more objects containing properties. >+ */ >+var replaceParams = function(str) { >+ var args = arguments; >+ return str.replace(replaceRE, function(str, p1, offset, s) { >+ for (var ii = 1; ii < args.length; ++ii) { >+ if (args[ii][p1] !== undefined) { >+ return args[ii][p1]; >+ } >+ } >+ throw "unknown string param '" + p1 + "'"; >+ }); >+}; >+ >+var upperCaseFirstLetter = function(str) { >+ return str.substring(0, 1).toUpperCase() + str.substring(1); >+}; >+ >+/** >+ * Gets a prefixed property. For example, >+ * >+ * var fn = getPrefixedProperty( >+ * window, >+ * "requestAnimationFrame"); >+ * >+ * Will return either: >+ * "window.requestAnimationFrame", >+ * "window.oRequestAnimationFrame", >+ * "window.msRequestAnimationFrame", >+ * "window.mozRequestAnimationFrame", >+ * "window.webKitRequestAnimationFrame", >+ * undefined >+ * >+ * the non-prefixed function is tried first. >+ */ >+var propertyPrefixes = ["", "moz", "ms", "o", "webkit"]; >+var getPrefixedProperty = function(obj, propertyName) { >+ for (var ii = 0; ii < propertyPrefixes.length; ++ii) { >+ var prefix = propertyPrefixes[ii]; >+ var name = prefix + propertyName; >+ log(name); >+ var property = obj[name]; >+ if (property) { >+ return property; >+ } >+ if (ii == 0) { >+ propertyName = upperCaseFirstLetter(propertyName); >+ } >+ } >+ return undefined; >+}; >+ >+var _requestAnimFrame; >+ >+/** >+ * Provides requestAnimationFrame in a cross browser way. >+ */ >+var requestAnimFrame = function(callback) { >+ if (!_requestAnimFrame) { >+ _requestAnimFrame = getPrefixedProperty(window, "requestAnimationFrame") || >+ function(callback, element) { >+ return window.setTimeout(callback, 1000 / 70); >+ }; >+ } >+ _requestAnimFrame.call(window, callback); >+}; >+ >+var _cancelAnimFrame; >+ >+/** >+ * Provides cancelAnimationFrame in a cross browser way. >+ */ >+var cancelAnimFrame = function(request) { >+ if (!_cancelAnimFrame) { >+ _cancelAnimFrame = getPrefixedProperty(window, "cancelAnimationFrame") || >+ window.clearTimeout; >+ } >+ _cancelAnimFrame.call(window, request); >+}; >+ >+/** >+ * Provides requestFullScreen in a cross browser way. >+ */ >+var requestFullScreen = function(element) { >+ var fn = getPrefixedProperty(element, "requestFullScreen"); >+ if (fn) { >+ fn.call(element); >+ } >+}; >+ >+/** >+ * Provides cancelFullScreen in a cross browser way. >+ */ >+var cancelFullScreen = function() { >+ var fn = getPrefixedProperty(document, "cancelFullScreen"); >+ if (fn) { >+ fn.call(document); >+ } >+}; >+ >+var fullScreenStateName; >+(function() { >+ var fullScreenStateNames = [ >+ "isFullScreen", >+ "fullScreen" >+ ]; >+ for (var ii = 0; ii < fullScreenStateNames.length; ++ii) { >+ var propertyName = fullScreenStateNames[ii]; >+ for (var jj = 0; jj < propertyPrefixes.length; ++jj) { >+ var prefix = propertyPrefixes[jj]; >+ if (prefix.length) { >+ propertyName = upperCaseFirstLetter(propertyName); >+ fullScreenStateName = prefix + propertyName; >+ if (document[fullScreenStateName] !== undefined) { >+ return; >+ } >+ } >+ } >+ fullScreenStateName = undefined; >+ } >+}()); >+ >+/** >+ * @return {boolean} True if fullscreen mode is active. >+ */ >+var getFullScreenState = function() { >+ log("fullscreenstatename:" + fullScreenStateName); >+ log(document[fullScreenStateName]); >+ return document[fullScreenStateName]; >+}; >+ >+/** >+ * @param {!HTMLElement} element The element to go fullscreen. >+ * @param {!function(boolean)} callback A function that will be called >+ * when entering/exiting fullscreen. It is passed true if >+ * entering fullscreen, false if exiting. >+ */ >+var onFullScreenChange = function(element, callback) { >+ propertyPrefixes.forEach(function(prefix) { >+ var eventName = prefix + "fullscreenchange"; >+ log("addevent: " + eventName); >+ document.addEventListener(eventName, function(event) { >+ log("event: " + eventName); >+ callback(getFullScreenState()); >+ }); >+ }); >+}; >+ >+/** >+ * @param {!string} buttonId The id of the button that will toggle fullscreen >+ * mode. >+ * @param {!string} fullscreenId The id of the element to go fullscreen. >+ * @param {!function(boolean)} callback A function that will be called >+ * when entering/exiting fullscreen. It is passed true if >+ * entering fullscreen, false if exiting. >+ * @return {boolean} True if fullscreen mode is supported. >+ */ >+var setupFullscreen = function(buttonId, fullscreenId, callback) { >+ if (!fullScreenStateName) { >+ return false; >+ } >+ >+ var fullscreenElement = document.getElementById(fullscreenId); >+ onFullScreenChange(fullscreenElement, callback); >+ >+ var toggleFullScreen = function(event) { >+ if (getFullScreenState()) { >+ cancelFullScreen(fullscreenElement); >+ } else { >+ requestFullScreen(fullscreenElement); >+ } >+ event.preventDefault(); >+ return false; >+ }; >+ >+ var buttonElement = document.getElementById(buttonId); >+ buttonElement.addEventListener('click', toggleFullScreen); >+ >+ return true; >+}; >+ >+/** >+ * Waits for the browser to composite the web page. >+ * @param {function()} callback A function to call after compositing has taken >+ * place. >+ */ >+var waitForComposite = function(callback) { >+ var frames = 5; >+ var countDown = function() { >+ if (frames == 0) { >+ // TODO(kbr): unify with js-test-pre.js and enable these with >+ // verbose logging. >+ // log("waitForComposite: callback"); >+ callback(); >+ } else { >+ // log("waitForComposite: countdown(" + frames + ")"); >+ --frames; >+ requestAnimFrame.call(window, countDown); >+ } >+ }; >+ countDown(); >+}; >+ >+/** >+ * Runs an array of functions, yielding to the browser between each step. >+ * If you want to know when all the steps are finished add a last step. >+ * @param {!Array.<function(): void>} steps Array of functions. >+ */ >+var runSteps = function(steps) { >+ if (!steps.length) { >+ return; >+ } >+ >+ // copy steps so they can't be modifed. >+ var stepsToRun = steps.slice(); >+ var currentStep = 0; >+ var runNextStep = function() { >+ stepsToRun[currentStep++](); >+ if (currentStep < stepsToRun.length) { >+ setTimeout(runNextStep, 1); >+ } >+ }; >+ runNextStep(); >+}; >+ >+/** >+ * Starts playing a video and waits for it to be consumable. >+ * @param {!HTMLVideoElement} video An HTML5 Video element. >+ * @param {!function(!HTMLVideoElement): void} callback Function to call when >+ * video is ready. >+ */ >+var startPlayingAndWaitForVideo = function(video, callback) { >+ var gotPlaying = false; >+ var gotTimeUpdate = false; >+ >+ var maybeCallCallback = function() { >+ if (gotPlaying && gotTimeUpdate && callback) { >+ callback(video); >+ callback = undefined; >+ video.removeEventListener('playing', playingListener, true); >+ video.removeEventListener('timeupdate', timeupdateListener, true); >+ } >+ }; >+ >+ var playingListener = function() { >+ gotPlaying = true; >+ maybeCallCallback(); >+ }; >+ >+ var timeupdateListener = function() { >+ // Checking to make sure the current time has advanced beyond >+ // the start time seems to be a reliable heuristic that the >+ // video element has data that can be consumed. >+ if (video.currentTime > 0.0) { >+ gotTimeUpdate = true; >+ maybeCallCallback(); >+ } >+ }; >+ >+ video.addEventListener('playing', playingListener, true); >+ video.addEventListener('timeupdate', timeupdateListener, true); >+ video.loop = true; >+ video.play(); >+}; >+ >+var getHost = function(url) { >+ url = url.replace("\\", "/"); >+ var pos = url.indexOf("://"); >+ if (pos >= 0) { >+ url = url.substr(pos + 3); >+ } >+ var parts = url.split('/'); >+ return parts[0]; >+} >+ >+// This function returns the last 2 words of the domain of a URL >+// This is probably not the correct check but it will do for now. >+var getBaseDomain = function(host) { >+ var parts = host.split(":"); >+ var hostname = parts[0]; >+ var port = parts[1] || "80"; >+ parts = hostname.split("."); >+ if(parts.length < 2) >+ return hostname + ":" + port; >+ var tld = parts[parts.length-1]; >+ var domain = parts[parts.length-2]; >+ return domain + "." + tld + ":" + port; >+} >+ >+var runningOnLocalhost = function() { >+ return window.location.hostname.indexOf("localhost") != -1 || >+ window.location.hostname.indexOf("127.0.0.1") != -1; >+} >+ >+var getLocalCrossOrigin = function() { >+ var domain; >+ if (window.location.host.indexOf("localhost") != -1) { >+ domain = "127.0.0.1"; >+ } else { >+ domain = "localhost"; >+ } >+ >+ var port = window.location.port || "80"; >+ return window.location.protocol + "//" + domain + ":" + port >+} >+ >+var getRelativePath = function(path) { >+ var relparts = window.location.pathname.split("/"); >+ relparts.pop(); // Pop off filename >+ var pathparts = path.split("/"); >+ >+ var i; >+ for (i = 0; i < pathparts.length; ++i) { >+ switch (pathparts[i]) { >+ case "": break; >+ case ".": break; >+ case "..": >+ relparts.pop(); >+ break; >+ default: >+ relparts.push(pathparts[i]); >+ break; >+ } >+ } >+ >+ return relparts.join("/"); >+} >+ >+var setupImageForCrossOriginTest = function(img, imgUrl, localUrl, callback) { >+ window.addEventListener("load", function() { >+ if (typeof(img) == "string") >+ img = document.querySelector(img); >+ if (!img) >+ img = new Image(); >+ >+ img.addEventListener("load", callback, false); >+ img.addEventListener("error", callback, false); >+ >+ if (runningOnLocalhost()) >+ img.src = getLocalCrossOrigin() + getRelativePath(localUrl); >+ else >+ img.src = getUrlOptions().imgUrl || imgUrl; >+ }, false); >+} >+ >+/** >+ * Convert sRGB color to linear color. >+ * @param {!Array.<number>} color The color to be converted. >+ * The array has 4 elements, for example [R, G, B, A]. >+ * where each element is in the range 0 to 255. >+ * @return {!Array.<number>} color The color to be converted. >+ * The array has 4 elements, for example [R, G, B, A]. >+ * where each element is in the range 0 to 255. >+ */ >+var sRGBToLinear = function(color) { >+ return [sRGBChannelToLinear(color[0]), >+ sRGBChannelToLinear(color[1]), >+ sRGBChannelToLinear(color[2]), >+ color[3]] >+} >+ >+/** >+ * Convert linear color to sRGB color. >+ * @param {!Array.<number>} color The color to be converted. >+ * The array has 4 elements, for example [R, G, B, A]. >+ * where each element is in the range 0 to 255. >+ * @return {!Array.<number>} color The color to be converted. >+ * The array has 4 elements, for example [R, G, B, A]. >+ * where each element is in the range 0 to 255. >+ */ >+var linearToSRGB = function(color) { >+ return [linearChannelToSRGB(color[0]), >+ linearChannelToSRGB(color[1]), >+ linearChannelToSRGB(color[2]), >+ color[3]] >+} >+ >+function sRGBChannelToLinear(value) { >+ value = value / 255; >+ if (value <= 0.04045) >+ value = value / 12.92; >+ else >+ value = Math.pow((value + 0.055) / 1.055, 2.4); >+ return Math.trunc(value * 255 + 0.5); >+} >+ >+function linearChannelToSRGB(value) { >+ value = value / 255; >+ if (value <= 0.0) { >+ value = 0.0; >+ } else if (value < 0.0031308) { >+ value = value * 12.92; >+ } else if (value < 1) { >+ value = Math.pow(value, 0.41666) * 1.055 - 0.055; >+ } else { >+ value = 1.0; >+ } >+ return Math.trunc(value * 255 + 0.5); >+} >+ >+function comparePixels(cmp, ref, tolerance, diff) { >+ if (cmp.length != ref.length) { >+ testFailed("invalid pixel size."); >+ } >+ >+ var count = 0; >+ for (var i = 0; i < cmp.length; i++) { >+ diff[i * 4] = 0; >+ diff[i * 4 + 1] = 255; >+ diff[i * 4 + 2] = 0; >+ diff[i * 4 + 3] = 255; >+ if (Math.abs(cmp[i * 4] - ref[i * 4]) > tolerance || >+ Math.abs(cmp[i * 4 + 1] - ref[i * 4 + 1]) > tolerance || >+ Math.abs(cmp[i * 4 + 2] - ref[i * 4 + 2]) > tolerance || >+ Math.abs(cmp[i * 4 + 3] - ref[i * 4 + 3]) > tolerance) { >+ if (count < 10) { >+ testFailed("Pixel " + i + ": expected (" + >+ [ref[i * 4], ref[i * 4 + 1], ref[i * 4 + 2], ref[i * 4 + 3]] + "), got (" + >+ [cmp[i * 4], cmp[i * 4 + 1], cmp[i * 4 + 2], cmp[i * 4 + 3]] + ")"); >+ } >+ count++; >+ diff[i * 4] = 255; >+ diff[i * 4 + 1] = 0; >+ } >+ } >+ >+ return count; >+} >+ >+function displayImageDiff(cmp, ref, diff, width, height) { >+ var div = document.createElement("div"); >+ >+ var cmpImg = createImageFromPixel(cmp, width, height); >+ var refImg = createImageFromPixel(ref, width, height); >+ var diffImg = createImageFromPixel(diff, width, height); >+ wtu.insertImage(div, "Reference", refImg); >+ wtu.insertImage(div, "Result", cmpImg); >+ wtu.insertImage(div, "Difference", diffImg); >+ >+ var console = document.getElementById("console"); >+ console.appendChild(div); >+} >+ >+function createImageFromPixel(buf, width, height) { >+ var canvas = document.createElement("canvas"); >+ canvas.width = width; >+ canvas.height = height; >+ var ctx = canvas.getContext("2d"); >+ var imgData = ctx.getImageData(0, 0, width, height); >+ >+ for (var i = 0; i < buf.length; i++) >+ imgData.data[i] = buf[i]; >+ ctx.putImageData(imgData, 0, 0); >+ var img = wtu.makeImageFromCanvas(canvas); >+ return img; >+} >+ >+var API = { >+ addShaderSource: addShaderSource, >+ addShaderSources: addShaderSources, >+ cancelAnimFrame: cancelAnimFrame, >+ create3DContext: create3DContext, >+ GLErrorException: GLErrorException, >+ create3DContextWithWrapperThatThrowsOnGLError: create3DContextWithWrapperThatThrowsOnGLError, >+ checkAreaInAndOut: checkAreaInAndOut, >+ checkCanvas: checkCanvas, >+ checkCanvasRect: checkCanvasRect, >+ checkCanvasRectColor: checkCanvasRectColor, >+ checkCanvasRects: checkCanvasRects, >+ checkFloatBuffer: checkFloatBuffer, >+ checkTextureSize: checkTextureSize, >+ clipToRange: clipToRange, >+ createColoredTexture: createColoredTexture, >+ createProgram: createProgram, >+ clearAndDrawUnitQuad: clearAndDrawUnitQuad, >+ clearAndDrawIndexedQuad: clearAndDrawIndexedQuad, >+ comparePixels: comparePixels, >+ displayImageDiff: displayImageDiff, >+ drawUnitQuad: drawUnitQuad, >+ drawIndexedQuad: drawIndexedQuad, >+ drawUByteColorQuad: drawUByteColorQuad, >+ drawFloatColorQuad: drawFloatColorQuad, >+ dummySetProgramAndDrawNothing: dummySetProgramAndDrawNothing, >+ dumpShadersInfo: dumpShadersInfo, >+ endsWith: endsWith, >+ failIfGLError: failIfGLError, >+ fillTexture: fillTexture, >+ getBytesPerComponent: getBytesPerComponent, >+ getDefault3DContextVersion: getDefault3DContextVersion, >+ getExtensionPrefixedNames: getExtensionPrefixedNames, >+ getExtensionWithKnownPrefixes: getExtensionWithKnownPrefixes, >+ getFileListAsync: getFileListAsync, >+ getLastError: getLastError, >+ getPrefixedProperty: getPrefixedProperty, >+ getScript: getScript, >+ getSupportedExtensionWithKnownPrefixes: getSupportedExtensionWithKnownPrefixes, >+ getTypedArrayElementsPerPixel: getTypedArrayElementsPerPixel, >+ getUrlArguments: getUrlArguments, >+ getUrlOptions: getUrlOptions, >+ getAttribMap: getAttribMap, >+ getUniformMap: getUniformMap, >+ glEnumToString: glEnumToString, >+ glErrorShouldBe: glErrorShouldBe, >+ glTypeToTypedArrayType: glTypeToTypedArrayType, >+ hasAttributeCaseInsensitive: hasAttributeCaseInsensitive, >+ insertImage: insertImage, >+ loadImageAsync: loadImageAsync, >+ loadImagesAsync: loadImagesAsync, >+ loadProgram: loadProgram, >+ loadProgramFromFile: loadProgramFromFile, >+ loadProgramFromScript: loadProgramFromScript, >+ loadProgramFromScriptExpectError: loadProgramFromScriptExpectError, >+ loadShader: loadShader, >+ loadShaderFromFile: loadShaderFromFile, >+ loadShaderFromScript: loadShaderFromScript, >+ loadStandardProgram: loadStandardProgram, >+ loadStandardProgramAsync: loadStandardProgramAsync, >+ loadStandardVertexShader: loadStandardVertexShader, >+ loadStandardVertexShaderAsync: loadStandardVertexShaderAsync, >+ loadStandardFragmentShader: loadStandardFragmentShader, >+ loadStandardFragmentShaderAsync: loadStandardFragmentShaderAsync, >+ loadUniformBlockProgram: loadUniformBlockProgram, >+ loadUniformBlockVertexShader: loadUniformBlockVertexShader, >+ loadUniformBlockFragmentShader: loadUniformBlockFragmentShader, >+ loadTextFileAsync: loadTextFileAsync, >+ loadTexture: loadTexture, >+ log: log, >+ loggingOff: loggingOff, >+ makeCheckRect: makeCheckRect, >+ makeImage: makeImage, >+ makeImageFromCanvas: makeImageFromCanvas, >+ makeVideo: makeVideo, >+ error: error, >+ shallowCopyObject: shallowCopyObject, >+ setDefault3DContextVersion: setDefault3DContextVersion, >+ setupColorQuad: setupColorQuad, >+ setupProgram: setupProgram, >+ setupTransformFeedbackProgram: setupTransformFeedbackProgram, >+ setupQuad: setupQuad, >+ setupQuadWithTexCoords: setupQuadWithTexCoords, >+ setupIndexedQuad: setupIndexedQuad, >+ setupIndexedQuadWithOptions: setupIndexedQuadWithOptions, >+ setupSimpleColorProgram: setupSimpleColorProgram, >+ setupSimpleTextureProgram: setupSimpleTextureProgram, >+ setupSimpleCubeMapTextureProgram: setupSimpleCubeMapTextureProgram, >+ setupSimpleVertexColorProgram: setupSimpleVertexColorProgram, >+ setupNoTexCoordTextureProgram: setupNoTexCoordTextureProgram, >+ setupTexturedQuad: setupTexturedQuad, >+ setupTexturedQuadWithTexCoords: setupTexturedQuadWithTexCoords, >+ setupTexturedQuadWithCubeMap: setupTexturedQuadWithCubeMap, >+ setupUnitQuad: setupUnitQuad, >+ setFloatDrawColor: setFloatDrawColor, >+ setUByteDrawColor: setUByteDrawColor, >+ startPlayingAndWaitForVideo: startPlayingAndWaitForVideo, >+ startsWith: startsWith, >+ shouldGenerateGLError: shouldGenerateGLError, >+ readFile: readFile, >+ readFileList: readFileList, >+ replaceParams: replaceParams, >+ requestAnimFrame: requestAnimFrame, >+ runSteps: runSteps, >+ waitForComposite: waitForComposite, >+ >+ // fullscreen api >+ setupFullscreen: setupFullscreen, >+ >+ // sRGB converter api >+ sRGBToLinear: sRGBToLinear, >+ linearToSRGB: linearToSRGB, >+ >+ getHost: getHost, >+ getBaseDomain: getBaseDomain, >+ runningOnLocalhost: runningOnLocalhost, >+ getLocalCrossOrigin: getLocalCrossOrigin, >+ getRelativePath: getRelativePath, >+ setupImageForCrossOriginTest: setupImageForCrossOriginTest, >+ >+ none: false >+}; >+ >+Object.defineProperties(API, { >+ noTexCoordTextureVertexShader: { value: noTexCoordTextureVertexShader, writable: false }, >+ simpleTextureVertexShader: { value: simpleTextureVertexShader, writable: false }, >+ simpleColorFragmentShader: { value: simpleColorFragmentShader, writable: false }, >+ simpleColorFragmentShaderESSL300: { value: simpleColorFragmentShaderESSL300, writable: false }, >+ simpleVertexShader: { value: simpleVertexShader, writable: false }, >+ simpleTextureFragmentShader: { value: simpleTextureFragmentShader, writable: false }, >+ simpleCubeMapTextureFragmentShader: { value: simpleCubeMapTextureFragmentShader, writable: false }, >+ simpleVertexColorFragmentShader: { value: simpleVertexColorFragmentShader, writable: false }, >+ simpleVertexColorVertexShader: { value: simpleVertexColorVertexShader, writable: false } >+}); >+ >+return API; >+ >+}()); >diff --git a/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc-expected.txt b/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7bd5fa907585a58c3517a16bdda8123ef4318ddc >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc-expected.txt >@@ -0,0 +1,16 @@ >+This test verifies the functionality of the WEBGL_compressed_texture_astc extension, if it is available. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS WebGL context exists >+Testing binding enum with extension disabled >+PASS supportedFormats is [] >+ >+PASS No WEBGL_compressed_texture_astc support -- this is legal >+PASS WEBGL_compressed_texture_astc not listed as supported and getExtension failed -- this is legal >+ >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc.html b/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b4bfd0ff40ce870dcdf35ab358b44b46248c0d9b >--- /dev/null >+++ b/LayoutTests/fast/canvas/webgl/webgl-compressed-texture-astc.html >@@ -0,0 +1,2078 @@ >+<!-- >+/* >+** Copyright (c) 2016 The Khronos Group Inc. >+** >+** Permission is hereby granted, free of charge, to any person obtaining a >+** copy of this software and/or associated documentation files (the >+** "Materials"), to deal in the Materials without restriction, including >+** without limitation the rights to use, copy, modify, merge, publish, >+** distribute, sublicense, and/or sell copies of the Materials, and to >+** permit persons to whom the Materials are furnished to do so, subject to >+** the following conditions: >+** >+** The above copyright notice and this permission notice shall be included >+** in all copies or substantial portions of the Materials. >+** >+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. >+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY >+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, >+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE >+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. >+*/ >+--> >+ >+<!DOCTYPE html> >+<html> >+<head> >+<meta charset="utf-8"> >+<link rel="stylesheet" href="./resources/js-test-style.css"/> >+<script src="./resources/js-test-pre.js"></script> >+<script src="./resources/webgl-test-utils-khr.js"></script> >+<title>WebGL WEBGL_compressed_texture_astc Conformance Tests</title> >+<style> >+img { >+ border: 1px solid black; >+ margin-right: 1em; >+} >+.testimages { >+} >+ >+.testimages br { >+ clear: both; >+} >+ >+.testimages > div { >+ float: left; >+ margin: 1em; >+} >+</style> >+</head> >+<body> >+<div id="description"></div> >+<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas> >+<div id="console"></div> >+<script> >+"use strict"; >+description("This test verifies the functionality of the WEBGL_compressed_texture_astc extension, if it is available."); >+ >+debug(""); >+ >+// Compressed textures generated with ARM's ASTC encoder >+// https://github.com/ARM-software/astc-encoder >+ >+// The data below is printed directly from the astc file, >+// and the header has been left for clarity reasons. >+ >+// LDR encoded with the following command line: >+// 'astcenc -c source.png result.astc {blockSize} -medium' >+ >+// The image used for LDR compression can be found >+// at sdk/tests/resources/red-green-hard.png >+ >+var astc_4x4_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x4, 0x4, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0x0, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_5x4_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x5, 0x4, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xc1, 0x2, 0x1, 0x2, 0x1, 0x0, 0x0, 0x80, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x9, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x20, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x2, 0x1, 0x0, 0x0, 0x80, 0x48, 0x22, 0x89, 0x24, 0x0, 0x40, 0x0, 0x80, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, >+]); >+var astc_5x5_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x5, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xf3, 0x0, 0x81, 0xff, 0x7, 0x0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xf3, 0x0, 0x7f, 0x0, 0xf8, 0x1, 0xe0, 0xff, 0xf1, 0xff, 0xf8, 0x7f, 0x0, 0x0, 0x0, 0x0, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, >+]); >+var astc_6x5_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x6, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x48, 0x49, 0x29, 0x29, 0x25, 0xa5, 0xa4, 0x94, 0x94, 0x12, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x48, 0x0, 0x28, 0x0, 0x24, 0x0, 0xa4, 0x94, 0x94, 0x92, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x0, 0x48, 0x1, 0x28, 0x1, 0xa4, 0x0, 0x94, 0x0, 0x92, >+]); >+var astc_6x6_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x6, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xc3, 0x30, 0xfc, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xe3, 0xf8, 0xff, 0xff, >+]); >+var astc_8x5_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xff, 0xf, 0xff, 0xf, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x66, 0x0, 0x3f, 0x0, 0x1f, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, >+]); >+var astc_8x6_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0xf8, 0x7f, 0x56, 0x3f, 0x72, 0x7f, 0x7f, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0x7f, 0x3f, 0x72, 0x78, 0x7f, 0x70, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x50, 0x7f, 0x72, 0xfe, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, >+]); >+var astc_8x8_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x8, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, >+]); >+var astc_10x5_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x65, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x65, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0x0, 0xfc, 0xf0, 0xc3, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x65, 0x1, 0xff, 0x1, 0x0, 0xfe, 0x1, 0x0, 0x0, 0xc0, 0x7, 0x1f, 0x7c, 0xf0, 0xc1, 0x7, >+]); >+var astc_10x6_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xa4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xa4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xf0, 0xc3, 0xf, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xa4, 0x1, 0x1, 0xfe, 0xff, 0x1, 0x0, 0x0, 0x0, 0x3e, 0xf8, 0xe0, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_10x8_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x8, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x65, 0x9, 0x69, 0x35, 0x0, 0x8, 0x10, 0x2, 0x0, 0x0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x6, 0x11, 0x69, 0x2d, 0x80, 0x40, 0x2, 0x80, 0x4, 0x0, 0x8, 0x0, 0xff, 0xf, 0xf0, 0xff, >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_10x10_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0xa, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xa4, 0xc9, 0xc, 0x3, 0x22, 0x0, 0x8, 0x40, 0x8, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x45, 0x89, 0x7, 0x35, 0x0, 0x40, 0x10, 0x0, 0x20, 0x0, 0x0, 0x1f, 0x7c, 0xf0, 0xc1, 0xff, >+]); >+var astc_12x10_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xc, 0xa, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x64, 0x8, 0x11, 0x3, 0x22, 0x0, 0x8, 0x40, 0x38, 0xfc, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xe5, 0x10, 0x4a, 0x4d, 0x46, 0x7f, 0x0, 0xc0, 0xf, 0x40, 0xf8, 0x1, 0x39, 0xf1, 0x7, 0x0, >+]); >+var astc_12x12_argb_ldr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xc, 0xc, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x64, 0xa8, 0x21, 0x3, 0x22, 0x0, 0x8, 0x40, 0x38, 0xfc, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x84, 0xd8, 0xe9, 0x2e, 0x0, 0x0, 0x1, 0x0, 0x80, 0xc0, 0x80, 0x28, 0x2a, 0xab, 0x2a, 0xff, >+]); >+ >+// HDR encoded with the following command line: >+// 'astcenc -c source.hdr result.astc {blockSize} -medium' >+ >+// The image used for HDR compression can be found >+// at sdk/tests/resources/red-green-hard.hdr >+ >+var astc_4x4_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x4, 0x4, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x42, 0x2, 0x1, 0x82, 0x82, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x81, 0x3, 0x82, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x42, 0x2, 0x81, 0x3, 0x82, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x83, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, >+ 0x42, 0x2, 0x83, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x42, 0x2, 0x1, 0x82, 0x82, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_5x4_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x5, 0x4, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xc1, 0x2, 0x1, 0x42, 0x21, 0x0, 0x0, 0x80, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x9, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x42, 0x21, 0x0, 0x0, 0x0, 0x0, 0x20, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x42, 0x21, 0x0, 0x0, 0x80, 0x48, 0x22, 0x89, 0x24, 0x0, 0x40, 0x0, 0x80, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xc1, 0x2, 0x1, 0x42, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, >+]); >+var astc_5x5_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x5, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xf3, 0x0, 0x81, 0xff, 0x7, 0x0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xf3, 0x0, 0x81, 0xff, 0x7, 0x0, 0x0, 0x0, 0xe, 0x0, 0x7, 0x80, 0xff, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, >+]); >+var astc_6x5_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x6, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x48, 0x49, 0x29, 0x29, 0x25, 0xa5, 0xa4, 0x94, 0x94, 0x12, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x48, 0x0, 0x28, 0x0, 0x24, 0x0, 0xa4, 0x94, 0x94, 0x92, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x63, 0x1, 0x81, 0x10, 0x0, 0x0, 0x0, 0x48, 0x1, 0x28, 0x1, 0xa4, 0x0, 0x94, 0x0, 0x92, >+]); >+var astc_6x6_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x6, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xc3, 0x30, 0xfc, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xe3, 0xf8, 0xff, 0xff, >+]); >+var astc_8x5_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xff, 0xf, 0xff, 0xf, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x66, 0x0, 0xc1, 0xff, 0x0, 0x0, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, >+]); >+var astc_8x6_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x3f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0xf8, 0x7f, 0x56, 0x3f, 0x72, 0x7f, 0x7f, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x70, 0x7f, 0x7f, 0x7f, 0x3f, 0x72, 0x78, 0x7f, 0x70, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x54, 0x1, 0x81, 0x20, 0x0, 0x0, 0x50, 0x7f, 0x72, 0xfe, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, >+]); >+var astc_8x8_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0x8, 0x8, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x44, 0x5, 0x81, 0x3, 0x82, 0x0, 0x0, 0x0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0x44, 0x5, 0x81, 0x3, 0x82, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+ 0x44, 0x5, 0x1, 0x82, 0x82, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfc, >+ 0x44, 0x5, 0x1, 0x82, 0x82, 0x0, 0x0, 0x0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, >+]); >+var astc_10x5_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x5, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x65, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x65, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x0, 0xfc, 0xf0, 0xc3, 0xff, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x65, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xe0, 0x83, 0xf, 0x3e, 0xf8, >+]); >+var astc_10x6_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x6, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xa4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xa4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xf0, 0xc3, 0xf, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xa4, 0x1, 0x1, 0xfc, 0xfd, 0x1, 0x0, 0x0, 0x0, 0x3e, 0xf8, 0xe0, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_10x8_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0x8, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x65, 0x9, 0x69, 0x35, 0x0, 0x8, 0x10, 0x2, 0x0, 0x0, 0xfc, 0xe0, 0x3, 0x0, 0x0, 0x0, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x15, 0x11, 0x69, 0x25, 0x0, 0x84, 0x0, 0x10, 0x0, 0x2, 0x40, 0x88, 0x3f, 0x0, 0x3f, 0x0, >+ 0x44, 0x5, 0x1, 0x2, 0x2, 0x0, 0x0, 0x0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, >+]); >+var astc_10x10_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xa, 0xa, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0xa4, 0xc9, 0xc, 0x3, 0x22, 0x0, 0x8, 0x40, 0x8, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x45, 0x89, 0x7, 0x35, 0x0, 0x40, 0x0, 0x82, 0x0, 0x0, 0x0, 0xe0, 0x83, 0xf, 0x3e, 0x0, >+]); >+var astc_12x10_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xc, 0xa, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x64, 0x8, 0x11, 0x3, 0x22, 0x0, 0x8, 0x40, 0x38, 0xfc, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x44, 0x10, 0x4a, 0x49, 0x46, 0xf, 0x1c, 0x3f, 0x0, 0x28, 0xff, 0x1, 0xc0, 0x3f, 0xc, 0x0, >+]); >+var astc_12x12_argb_hdr = new Uint8Array([ >+ //0x13, 0xab, 0xa1, 0x5c, 0xc, 0xc, 0x1, 0x10, 0x0, 0x0, 0x10, 0x0, 0x0, 0x1, 0x0, 0x0, HEADER >+ 0x64, 0xa8, 0x21, 0x3, 0x22, 0x0, 0x8, 0x40, 0x38, 0xfc, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x7f, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, >+ 0x4, 0xd8, 0xe9, 0x2e, 0x0, 0x8, 0x1, 0x40, 0x80, 0xc0, 0x81, 0x28, 0x2a, 0x0, 0x0, 0x0, >+]); >+ >+// Decoded ASTC textures generated with ARM's ASTC encoder >+// https://github.com/ARM-software/astc-encoder >+ >+// As the original image is quite simple to compress, >+// several decoded images share the same data >+ >+// LDR decoded with the following command line: >+// 'astcenc -d source.astc result.tga' >+var decoded_4x4To10x6_argb_ldr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+]); >+var decoded_10x8_argb_ldr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xdf, 0x20, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+]); >+var decoded_10x10_argb_ldr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, >+ 0x20, 0xdf, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x8f, 0x70, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+]); >+var decoded_12x10_argb_ldr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xdf, 0x20, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+]); >+var decoded_12x12_argb_ldr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, >+ 0x10, 0xef, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, >+ 0x70, 0x8f, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, >+ 0xcf, 0x30, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xbf, 0x40, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x60, 0x9f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+]); >+ >+// HDR decoded with the following command line: >+// 'astcenc -d source.astc result.tga' >+ >+var decoded_4x4_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, >+ 0x0, 0xfd, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_5x4_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_5x5_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_6x5_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_6x6_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_8x5_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_8x6_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_8x8_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, >+ 0x0, 0xfd, 0x0, 0xff, 0x0, 0xfd, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xfd, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+ >+var decoded_10x5To10x6_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xfe, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+ >+var decoded_10x8_argb_hdr = new Uint8Array([ >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xdf, 0x20, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_10x10_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, >+ 0x20, 0xdf, 0x0, 0xff, 0x20, 0xdf, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x8f, 0x70, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_12x10_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xdf, 0x20, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+var decoded_12x12_argb_hdr = new Uint8Array([ >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0x0, 0xfe, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, >+ 0x10, 0xef, 0x0, 0xff, 0x10, 0xef, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, >+ 0x70, 0x8f, 0x0, 0xff, 0x70, 0x8f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, >+ 0xcf, 0x30, 0x0, 0xff, 0xcf, 0x30, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0xbf, 0x40, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x60, 0x9f, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+ 0x0, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, >+ 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0xff, >+]); >+ >+var wtu = WebGLTestUtils; >+var contextVersion = wtu.getDefault3DContextVersion(); >+var canvas = document.getElementById("canvas"); >+var gl = wtu.create3DContext(canvas, {antialias: false}); >+var program = wtu.setupTexturedQuad(gl); >+var extFlag = "WEBGL_compressed_texture_astc"; >+var ext = null; >+var vao = null; >+var validFormats = { >+ >+ COMPRESSED_RGBA_ASTC_4x4_KHR : 0x93B0, >+ COMPRESSED_RGBA_ASTC_5x4_KHR : 0x93B1, >+ COMPRESSED_RGBA_ASTC_5x5_KHR : 0x93B2, >+ COMPRESSED_RGBA_ASTC_6x5_KHR : 0x93B3, >+ COMPRESSED_RGBA_ASTC_6x6_KHR : 0x93B4, >+ COMPRESSED_RGBA_ASTC_8x5_KHR : 0x93B5, >+ COMPRESSED_RGBA_ASTC_8x6_KHR : 0x93B6, >+ COMPRESSED_RGBA_ASTC_8x8_KHR : 0x93B7, >+ COMPRESSED_RGBA_ASTC_10x5_KHR : 0x93B8, >+ COMPRESSED_RGBA_ASTC_10x6_KHR : 0x93B9, >+ COMPRESSED_RGBA_ASTC_10x8_KHR : 0x93BA, >+ COMPRESSED_RGBA_ASTC_10x10_KHR : 0x93BB, >+ COMPRESSED_RGBA_ASTC_12x10_KHR : 0x93BC, >+ COMPRESSED_RGBA_ASTC_12x12_KHR : 0x93BD, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : 0x93D0, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : 0x93D1, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : 0x93D2, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : 0x93D3, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : 0x93D4, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : 0x93D5, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : 0x93D6, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : 0x93D7, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : 0x93D8, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : 0x93D9, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : 0x93DA, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : 0x93DB, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : 0x93DC, >+ COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : 0x93DD >+ >+}; >+var name; >+var supportedFormats; >+ >+if (!gl) { >+ testFailed("WebGL context does not exist"); >+} else { >+ testPassed("WebGL context exists"); >+ >+ // Run tests with extension disabled >+ runTestDisabled(); >+ debug(""); >+ >+ // Query the extension and store globally so shouldBe can access it >+ ext = wtu.getExtensionWithKnownPrefixes(gl, extFlag); >+ if (!ext) { >+ testPassed("No WEBGL_compressed_texture_astc support -- this is legal"); >+ runSupportedTest(false); >+ } else { >+ testPassed("Successfully enabled WEBGL_compressed_texture_astc extension"); >+ >+ debug(""); >+ runSupportedTest(true); >+ runTestExtension(); >+ } >+} >+ >+function runSupportedTest(extensionEnabled) { >+ var name = wtu.getSupportedExtensionWithKnownPrefixes(gl, extFlag); >+ if (name !== undefined) { >+ if (extensionEnabled) { >+ testPassed("WEBGL_compressed_texture_astc listed as supported and getExtension succeeded"); >+ } else { >+ testFailed("WEBGL_compressed_texture_astc listed as supported but getExtension failed"); >+ } >+ } else { >+ if (extensionEnabled) { >+ testFailed("WEBGL_compressed_texture_astc not listed as supported but getExtension succeeded"); >+ } else { >+ testPassed("WEBGL_compressed_texture_astc not listed as supported and getExtension failed -- this is legal"); >+ } >+ } >+} >+ >+ >+function runTestDisabled() { >+ debug("Testing binding enum with extension disabled"); >+ >+ supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); >+ shouldBe("supportedFormats", "[]"); >+} >+ >+function runTestExtension() { >+ debug(""); >+ debug("Testing " + extFlag); >+ >+ supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); >+ // There should be exactly 28 formats for both WebGL 1.0 and WebGL 2.0. >+ shouldBe("supportedFormats.length", "28"); >+ >+ console.log(wtu); >+ >+ // check that all 28 formats exist >+ testFormatsExist(supportedFormats); >+ // check that all format enums exist. >+ testCompressionFormatsValidity(); >+ // check that the specified restrictions fails with >+ // an INVALID_VALUE error when not respected >+ testASTCFormatsRestrictions(); >+ // Tests ASTC texture with every format >+ testLDRTextures(); >+ testHDRTextures(); >+} >+ >+function testFormatsExist(supportedFormats) { >+ debug(""); >+ debug("Testing every supported formats exist"); >+ >+ var failed; >+ for (var name in validFormats) { >+ var format = validFormats[name]; >+ failed = true; >+ for (var ii = 0; ii < supportedFormats.length; ++ii) { >+ if (format == supportedFormats[ii]) { >+ testPassed("supported format " + formatToString(format) + " exists"); >+ failed = false; >+ break; >+ } >+ } >+ if (failed) { >+ testFailed("supported format " + formatToString(format) + " does not exist"); >+ } >+ } >+} >+ >+function testCompressionFormatsValidity() { >+ debug(""); >+ debug("Testing every supported formats is valid"); >+ >+ for (name in validFormats) { >+ var expected = "0x" + validFormats[name].toString(16); >+ var actual = "ext['" + name + "']"; >+ shouldBe(actual, expected); >+ } >+} >+ >+function testASTCFormatsRestrictions() { >+ debug(""); >+ debug("Testing format restrictions on buffer size"); >+ >+ var data = new Uint8Array(17); >+ >+ var tex = gl.createTexture(); >+ gl.bindTexture(gl.TEXTURE_2D, tex); >+ for (var formatId in validFormats) { >+ var format = validFormats[formatId]; >+ var expectedSize = expectedByteLength(16, 16, format, data.length); >+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, 16, 16, 0, data); >+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, >+ formatToString(format) + " expected size: " + expectedSize); >+ } >+} >+ >+function testLDRTextures() { >+ debug(""); >+ debug("Testing every LDR texture format compression"); >+ >+ var data = []; >+ var formats = []; >+ var raws = []; >+ >+ data.push(astc_4x4_argb_ldr, astc_5x4_argb_ldr, astc_5x5_argb_ldr, >+ astc_6x5_argb_ldr, astc_6x6_argb_ldr, astc_8x5_argb_ldr, >+ astc_8x6_argb_ldr, astc_8x8_argb_ldr, astc_10x5_argb_ldr, >+ astc_10x6_argb_ldr, astc_10x8_argb_ldr, astc_10x10_argb_ldr, >+ astc_12x10_argb_ldr, astc_12x12_argb_ldr); >+ >+ formats.push(ext.COMPRESSED_RGBA_ASTC_4x4_KHR, ext.COMPRESSED_RGBA_ASTC_5x4_KHR, >+ ext.COMPRESSED_RGBA_ASTC_5x5_KHR, ext.COMPRESSED_RGBA_ASTC_6x5_KHR, >+ ext.COMPRESSED_RGBA_ASTC_6x6_KHR, ext.COMPRESSED_RGBA_ASTC_8x5_KHR, >+ ext.COMPRESSED_RGBA_ASTC_8x6_KHR, ext.COMPRESSED_RGBA_ASTC_8x8_KHR, >+ ext.COMPRESSED_RGBA_ASTC_10x5_KHR, ext.COMPRESSED_RGBA_ASTC_10x6_KHR, >+ ext.COMPRESSED_RGBA_ASTC_10x8_KHR, ext.COMPRESSED_RGBA_ASTC_10x10_KHR, >+ ext.COMPRESSED_RGBA_ASTC_12x10_KHR, ext.COMPRESSED_RGBA_ASTC_12x12_KHR); >+ >+ // adds decoded image to use in the compare function >+ // certain block size share the same decoded data >+ // due to the fact that the test image is quite simple >+ for (var i = 0; i < 10; ++i) >+ raws.push(decoded_4x4To10x6_argb_ldr); >+ raws.push(decoded_10x8_argb_ldr, decoded_10x10_argb_ldr, decoded_12x10_argb_ldr, decoded_12x12_argb_ldr); >+ >+ testASTCTextures(buildTests(data, formats, raws, 'LDR')); >+} >+ >+function testHDRTextures() { >+ debug(""); >+ debug("Testing every HDR texture format compression"); >+ >+ >+ var data = []; >+ var formats = []; >+ var raws = []; >+ >+ data.push(astc_4x4_argb_hdr, astc_5x4_argb_hdr, astc_5x5_argb_hdr, >+ astc_6x5_argb_hdr, astc_6x6_argb_hdr, astc_8x5_argb_hdr, >+ astc_8x6_argb_hdr, astc_8x8_argb_hdr, astc_10x5_argb_hdr, >+ astc_10x6_argb_hdr, astc_10x8_argb_hdr, astc_10x10_argb_hdr, >+ astc_12x10_argb_hdr, astc_12x12_argb_hdr); >+ >+ formats.push(ext.COMPRESSED_RGBA_ASTC_4x4_KHR, ext.COMPRESSED_RGBA_ASTC_5x4_KHR, >+ ext.COMPRESSED_RGBA_ASTC_5x5_KHR, ext.COMPRESSED_RGBA_ASTC_6x5_KHR, >+ ext.COMPRESSED_RGBA_ASTC_6x6_KHR, ext.COMPRESSED_RGBA_ASTC_8x5_KHR, >+ ext.COMPRESSED_RGBA_ASTC_8x6_KHR, ext.COMPRESSED_RGBA_ASTC_8x8_KHR, >+ ext.COMPRESSED_RGBA_ASTC_10x5_KHR, ext.COMPRESSED_RGBA_ASTC_10x6_KHR, >+ ext.COMPRESSED_RGBA_ASTC_10x8_KHR, ext.COMPRESSED_RGBA_ASTC_10x10_KHR, >+ ext.COMPRESSED_RGBA_ASTC_12x10_KHR, ext.COMPRESSED_RGBA_ASTC_12x12_KHR); >+ >+ // adds decoded image to use in the compare function >+ // certain block size share the same decoded data >+ // due to the fact that the test image is quite simple >+ raws.push(decoded_4x4_argb_hdr, decoded_5x4_argb_hdr, decoded_5x5_argb_hdr, decoded_6x5_argb_hdr, >+ decoded_6x6_argb_hdr, decoded_8x5_argb_hdr, decoded_8x6_argb_hdr, decoded_8x8_argb_hdr, >+ decoded_10x5To10x6_argb_hdr, decoded_10x5To10x6_argb_hdr, decoded_10x8_argb_hdr, >+ decoded_10x10_argb_hdr, decoded_12x10_argb_hdr, decoded_12x12_argb_hdr); >+ >+ testASTCTextures(buildTests(data, formats, raws, 'HDR')); >+} >+ >+function testASTCTextures(tests) { >+ debug("<hr/>"); >+ for (var i = 0; i < tests.length; ++i) { >+ testASTCTexture(tests[i], false); >+ if (contextVersion >= 2) { >+ debug("<br/>"); >+ testASTCTexture(tests[i], true); >+ } >+ } >+} >+ >+function testASTCTexture(test, useTexStorage) { >+ var data = test.data; >+ var width = test.width; >+ var height = test.height; >+ var format = test.format; >+ var raw = test.raw; >+ >+ canvas.width = width; >+ canvas.height = height; >+ gl.viewport(0, 0, width, height); >+ debug(""); >+ debug("testing " + formatToString(format) + " " + width + "x" + height + " (" + test.mode + ")" + >+ (useTexStorage ? " via texStorage2D" : " via compressedTexImage2D")); >+ debug(""); >+ >+ // Texture upload >+ var tex = gl.createTexture(); >+ gl.bindTexture(gl.TEXTURE_2D, tex); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); >+ if (useTexStorage) { >+ gl.texStorage2D(gl.TEXTURE_2D, 1, format, width, height); >+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating compressed texture via texStorage2D"); >+ wtu.clearAndDrawUnitQuad(gl); >+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing unit quad"); >+ var clearColor = [0, 0, 0, 0]; >+ wtu.checkCanvas(gl, clearColor, "texture should be initialized to black"); >+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data); >+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture data via compressedTexSubImage2D"); >+ } else { >+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data); >+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture"); >+ } >+ >+ wtu.clearAndDrawUnitQuad(gl); >+ >+ // Check that the decoded image is consistent with NEAREST filtering >+ compareRect(width, height, test.channels, width, height, raw, data, format, undefined, "NEAREST"); >+ >+ // Check that the decoded image is consistent with LINEAR filtering >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); >+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); >+ wtu.clearAndDrawUnitQuad(gl); >+ compareRect(width, height, test.channels, width, height, raw, data, format, undefined, "LINEAR"); >+ >+ debug(""); >+ // Mipmaps handling >+ gl.generateMipmap(gl.TEXTURE_2D); >+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture"); >+ >+ if (!useTexStorage) { >+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data); >+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border"); >+ } >+ >+ debug(""); >+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data); >+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "compressedTexSubImage2D allowed for reloading of complete textures"); >+} >+ >+function compareRect( >+ actualWidth, actualHeight, actualChannels, >+ dataWidth, dataHeight, expectedData, >+ testData, testFormat, tolerance, filteringMode) { >+ >+ if(typeof(tolerance) == 'undefined') { tolerance = 5; } >+ var actual = new Uint8Array(actualWidth * actualHeight * 4); >+ gl.readPixels(0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual); >+ flipImage(actual, actualWidth, actualHeight); >+ >+ var div = document.createElement("div"); >+ div.className = "testimages"; >+ insertImg(div, "expected", makeImage( >+ actualWidth, actualHeight, dataWidth, expectedData, >+ actualChannels == 4)); >+ insertImg(div, "actual", makeImage( >+ actualWidth, actualHeight, actualWidth, actual, >+ actualChannels == 4)); >+ div.appendChild(document.createElement('br')); >+ document.getElementById("console").appendChild(div); >+ >+ var failed = false; >+ for (var yy = 0; yy < actualHeight; ++yy) { >+ for (var xx = 0; xx < actualWidth; ++xx) { >+ var actualOffset = (yy * actualWidth + xx) * 4; >+ var expectedOffset = (yy * dataWidth + xx) * 4; >+ var expected = [ >+ expectedData[expectedOffset + 0], >+ expectedData[expectedOffset + 1], >+ expectedData[expectedOffset + 2], >+ (actualChannels == 3 ? 255 : expectedData[expectedOffset + 3]) >+ ]; >+ for (var jj = 0; jj < 4; ++jj) { >+ if (Math.abs(actual[actualOffset + jj] - expected[jj]) > tolerance) { >+ failed = true; >+ var was = actual[actualOffset + 0].toString(); >+ for (var j = 1; j < 4; ++j) { >+ was += "," + actual[actualOffset + j]; >+ } >+ testFailed('at (' + xx + ', ' + yy + >+ ') expected: ' + expected + ' was ' + was); >+ } >+ } >+ } >+ } >+ if (!failed) { >+ testPassed("texture rendered correctly with " + filteringMode + " filtering"); >+ } >+} >+ >+// Builds several tests from two arrays >+// data gives each Uint8Array encoded data to use >+// formats the associate format to decode the data >+// raws gives each decoded Uint8Array data for texture comparison >+// mode 'LDR' or 'HDR' >+function buildTests(data, formats, raws, mode) { >+ >+ var tests = []; >+ for (var i = 0; i < data.length; ++i) { >+ var test = { >+ width: 16, >+ height: 16, >+ channels: 4, >+ data: data[i], >+ format: formats[i], >+ raw: raws[i], >+ mode: mode >+ }; >+ tests.push(test); >+ } >+ >+ return tests; >+} >+ >+function formatToString(format) { >+ for (var p in ext) { >+ if (ext[p] == format) { >+ return p; >+ } >+ } >+ return "0x" + format.toString(16); >+} >+ >+function expectedByteLength(w, h, format) { >+ >+ if (format == ext.COMPRESSED_RGBA_ASTC_4x4_KHR) >+ return Math.floor((w + 3) / 4) * Math.floor((h + 3) / 4) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_5x4_KHR) >+ return Math.floor((w + 4) / 5) * Math.floor((h + 3) / 4) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_5x5_KHR) >+ return Math.floor((w + 4) / 5) * Math.floor((h + 4) / 5) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_6x5_KHR) >+ return Math.floor((w + 5) / 6) * Math.floor((h + 4) / 5) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_6x6_KHR) >+ return Math.floor((w + 5) / 6) * Math.floor((h + 5) / 6) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_8x5_KHR) >+ return Math.floor((w + 7) / 8) * Math.floor((h + 4) / 5) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_8x6_KHR) >+ return Math.floor((w + 7) / 8) * Math.floor((h + 5) / 6) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_8x8_KHR) >+ return Math.floor((w + 7) / 8) * Math.floor((h + 7) / 8) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_10x5_KHR) >+ return Math.floor((w + 9) / 10) * Math.floor((h + 4) / 5) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_10x6_KHR) >+ return Math.floor((w + 9) / 10) * Math.floor((h + 5) / 6) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_10x8_KHR) >+ return Math.floor((w + 9) / 10) * Math.floor((h + 7) / 8) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_10x10_KHR) >+ return Math.floor((w + 9) / 10) * Math.floor((h + 9) / 10) * 16; >+ else if (format == ext.COMPRESSED_RGBA_ASTC_12x10_KHR) >+ return Math.floor((w + 11) / 12) * Math.floor((h + 9) / 10) * 16; >+ >+ return Math.floor((w + 11) / 12) * Math.floor((h + 11) / 12) * 16; >+} >+ >+function insertImg(element, caption, img) { >+ var div = document.createElement("div"); >+ div.appendChild(img); >+ var label = document.createElement("div"); >+ label.appendChild(document.createTextNode(caption)); >+ div.appendChild(label); >+ element.appendChild(div); >+} >+ >+function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) { >+ var scale = 8; >+ var c = document.createElement("canvas"); >+ c.width = imageWidth * scale; >+ c.height = imageHeight * scale; >+ var ctx = c.getContext("2d"); >+ for (var yy = 0; yy < imageHeight; ++yy) { >+ for (var xx = 0; xx < imageWidth; ++xx) { >+ var offset = (yy * dataWidth + xx) * 4; >+ ctx.fillStyle = "rgba(" + >+ data[offset + 0] + "," + >+ data[offset + 1] + "," + >+ data[offset + 2] + "," + >+ (alpha ? data[offset + 3] / 255 : 1) + ")"; >+ ctx.fillRect(xx * scale, yy * scale, scale, scale); >+ } >+ } >+ return wtu.makeImageFromCanvas(c); >+} >+ >+// Swaps two cells in an arraybuffer. >+// this function is used in the image flipping function >+function swapCell(array, i, j) { >+ var a = array[i]; >+ array[i] = array[j]; >+ array[j] = a; >+} >+ >+function flipImage(imgBuffer, w, h) { >+ var halfHeight = h / 2; >+ >+ for (var j = 0; j < halfHeight; j++) { >+ for (var i = 0; i < w; i++) { >+ var beginByte = (j * w + i) * 4; >+ var endByte = ((h - j - 1) * w + i) * 4; >+ >+ swapCell(imgBuffer, beginByte, endByte); >+ swapCell(imgBuffer, beginByte + 1, endByte + 1); >+ swapCell(imgBuffer, beginByte + 2, endByte + 2); >+ swapCell(imgBuffer, beginByte + 3, endByte + 3); >+ } >+ } >+} >+ >+debug(""); >+var successfullyParsed = true; >+</script> >+<script src="./resources/js-test-post.js"></script> >+ >+</body> >+</html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185272
:
339500
|
339503
|
339545
|
339607
|
339698
|
339777
|
339901
|
339905
|
339910
|
340005